udpate iso on film changed

This commit is contained in:
Vadim 2023-04-01 21:58:23 +03:00
parent 64281c4809
commit 6010dd9813
13 changed files with 152 additions and 122 deletions

View file

@ -7,7 +7,6 @@ import 'package:light_sensor/light_sensor.dart';
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/film_profile.dart';
import 'package:lightmeter/providers/supported_locale_provider.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
@ -49,7 +48,6 @@ class Application extends StatelessWidget {
Provider(create: (_) => const LightSensorService()),
],
child: StopTypeProvider(
child: FilmProvider(
child: EquipmentProfileProvider(
child: EvSourceTypeProvider(
child: SupportedLocaleProvider(
@ -81,7 +79,6 @@ class Application extends StatelessWidget {
),
),
),
),
);
}
return const SizedBox();

View file

@ -23,13 +23,13 @@ double log10polynomian(
/// do not have any reciprocity failure information, as these films are ment to be used in cinema
/// with appropriate light and pretty short shutter speeds.
///
class FilmData {
class Film {
final String name;
final int iso;
const FilmData(this.name, this.iso);
const Film(this.name, this.iso);
const FilmData.other()
const Film.other()
: name = 'Other',
iso = 0;
@ -51,8 +51,8 @@ class FilmData {
@protected
double reciprocityFormula(double t) => t;
static const List<FilmData> values = [
FilmData.other(),
static const List<Film> values = [
Film.other(),
FomapanFilm.creative100(),
FomapanFilm.creative200(),
FomapanFilm.action400(),
@ -78,7 +78,7 @@ class FilmData {
/// https://www.tate.org.uk/documents/598/page_6_7_agfa_stocks_0.pdf
/// https://www.filmwasters.com/forum/index.php?topic=5298.0
// {{1,1.87},{2,3.73},{3,8.06},{4,13.93},{5,21.28},{6,23.00},{7,30.12},{8,38.05},{9,44.75},{10,50.12},{20,117},{30,202},{40,293},{50,413},{60,547},{70,694},{80,853},{90,1022},{100,1202}};
class AgfaFilm extends FilmData {
class AgfaFilm extends Film {
final double a;
final double b;
final double c;
@ -99,7 +99,7 @@ class AgfaFilm extends FilmData {
double reciprocityFormula(double t) => t * log10polynomian(t, a, b, c);
}
class FomapanFilm extends FilmData {
class FomapanFilm extends Film {
final double a;
final double b;
final double c;
@ -126,7 +126,7 @@ class FomapanFilm extends FilmData {
super('Fomapan ACTION 400', 400);
}
class IlfordFilm extends FilmData {
class IlfordFilm extends Film {
final double reciprocityPower;
/// https://www.ilfordphoto.com/amfile/file/download/file/1948/product/1650/
@ -188,7 +188,7 @@ class IlfordFilm extends FilmData {
double reciprocityFormula(double t) => pow(t, reciprocityPower).toDouble();
}
class KodakFilm extends FilmData {
class KodakFilm extends Film {
final double a;
final double b;
final double c;

View file

@ -65,13 +65,16 @@ class UserPreferencesService {
}
}
IsoValue get iso => isoValues.firstWhere((v) => v.value == (_sharedPreferences.getInt(_isoKey) ?? 100));
IsoValue get iso =>
isoValues.firstWhere((v) => v.value == (_sharedPreferences.getInt(_isoKey) ?? 100));
set iso(IsoValue value) => _sharedPreferences.setInt(_isoKey, value.value);
NdValue get ndFilter => ndValues.firstWhere((v) => v.value == (_sharedPreferences.getInt(_ndFilterKey) ?? 0));
NdValue get ndFilter =>
ndValues.firstWhere((v) => v.value == (_sharedPreferences.getInt(_ndFilterKey) ?? 0));
set ndFilter(NdValue value) => _sharedPreferences.setInt(_ndFilterKey, value.value);
EvSourceType get evSourceType => EvSourceType.values[_sharedPreferences.getInt(_evSourceTypeKey) ?? 0];
EvSourceType get evSourceType =>
EvSourceType.values[_sharedPreferences.getInt(_evSourceTypeKey) ?? 0];
set evSourceType(EvSourceType value) => _sharedPreferences.setInt(_evSourceTypeKey, value.index);
bool get caffeine => _sharedPreferences.getBool(_caffeineKey) ?? false;
@ -87,10 +90,13 @@ class UserPreferencesService {
set locale(SupportedLocale value) => _sharedPreferences.setString(_localeKey, value.toString());
double get cameraEvCalibration => _sharedPreferences.getDouble(_cameraEvCalibrationKey) ?? 0.0;
set cameraEvCalibration(double value) => _sharedPreferences.setDouble(_cameraEvCalibrationKey, value);
set cameraEvCalibration(double value) =>
_sharedPreferences.setDouble(_cameraEvCalibrationKey, value);
double get lightSensorEvCalibration => _sharedPreferences.getDouble(_lightSensorEvCalibrationKey) ?? 0.0;
set lightSensorEvCalibration(double value) => _sharedPreferences.setDouble(_lightSensorEvCalibrationKey, value);
double get lightSensorEvCalibration =>
_sharedPreferences.getDouble(_lightSensorEvCalibrationKey) ?? 0.0;
set lightSensorEvCalibration(double value) =>
_sharedPreferences.setDouble(_lightSensorEvCalibrationKey, value);
ThemeType get themeType => ThemeType.values[_sharedPreferences.getInt(_themeTypeKey) ?? 0];
set themeType(ThemeType value) => _sharedPreferences.setInt(_themeTypeKey, value.index);
@ -101,11 +107,11 @@ class UserPreferencesService {
bool get dynamicColor => _sharedPreferences.getBool(_dynamicColorKey) ?? false;
set dynamicColor(bool value) => _sharedPreferences.setBool(_dynamicColorKey, value);
FilmData get film => FilmData.values.firstWhere(
Film get film => Film.values.firstWhere(
(e) => e.name == _sharedPreferences.getString(_filmKey),
orElse: () => FilmData.values.first,
orElse: () => Film.values.first,
);
set film(FilmData value) => _sharedPreferences.setString(_filmKey, value.name);
set film(Film value) => _sharedPreferences.setString(_filmKey, value.name);
String get selectedEquipmentProfileId => '';
set selectedEquipmentProfileId(String id) {}

View file

@ -1,63 +0,0 @@
import 'package:flutter/material.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/data/shared_prefs_service.dart';
import 'package:provider/provider.dart';
class FilmProvider extends StatefulWidget {
final Widget child;
const FilmProvider({required this.child, super.key});
static FilmProviderState of(BuildContext context) {
return context.findAncestorStateOfType<FilmProviderState>()!;
}
@override
State<FilmProvider> createState() => FilmProviderState();
}
class FilmProviderState extends State<FilmProvider> {
late FilmData _selectedFilm;
@override
void initState() {
super.initState();
_selectedFilm = context.read<UserPreferencesService>().film;
}
@override
Widget build(BuildContext context) {
return Film(
data: _selectedFilm,
child: widget.child,
);
}
void setFilm(FilmData data) {
setState(() {
_selectedFilm = data;
});
context.read<UserPreferencesService>().film = _selectedFilm;
}
}
class Film extends InheritedWidget {
final FilmData data;
const Film({
required this.data,
required super.child,
super.key,
});
static FilmData of(BuildContext context, {bool listen = true}) {
if (listen) {
return context.dependOnInheritedWidgetOfExactType<Film>()!.data;
} else {
return context.findAncestorWidgetOfExactType<Film>()!.data;
}
}
@override
bool updateShouldNotify(Film oldWidget) => true;
}

View file

@ -3,6 +3,7 @@ import 'dart:math';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:lightmeter/data/models/exposure_pair.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/data/shared_prefs_service.dart';
import 'package:lightmeter/interactors/metering_interactor.dart';
import 'package:lightmeter/screens/metering/communication/event_communication_metering.dart'
@ -31,6 +32,7 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
late IsoValue _iso = _userPreferencesService.iso;
late NdValue _nd = _userPreferencesService.ndFilter;
late Film _film = _userPreferencesService.film;
double _ev = 0.0;
bool _isMeteringInProgress = false;
@ -42,10 +44,11 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
this.stopType,
) : super(
MeteringEndedState(
iso: _userPreferencesService.iso,
ev: 0.0,
film: _userPreferencesService.film,
iso: _userPreferencesService.iso,
nd: _userPreferencesService.ndFilter,
exposurePairs: [],
exposurePairs: const [],
),
) {
_communicationSubscription = _communicationBloc.stream
@ -55,6 +58,7 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
on<EquipmentProfileChangedEvent>(_onEquipmentProfileChanged);
on<StopTypeChangedEvent>(_onStopTypeChanged);
on<FilmChangedEvent>(_onFilmChanged);
on<IsoChangedEvent>(_onIsoChanged);
on<NdChangedEvent>(_onNdChanged);
on<MeasureEvent>(_onMeasure);
@ -100,7 +104,23 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
_emitMeasuredState(emit);
}
void _onFilmChanged(FilmChangedEvent event, Emitter emit) {
if (_iso.value != event.data.iso) {
final newIso = isoValues.firstWhere(
(e) => e.value == event.data.iso,
orElse: () => _iso,
);
add(IsoChangedEvent(newIso));
}
_film = event.data;
_userPreferencesService.film = event.data;
_emitMeasuredState(emit);
}
void _onIsoChanged(IsoChangedEvent event, Emitter emit) {
if (event.isoValue.value != _film.iso) {
_film = Film.values.first;
}
_userPreferencesService.iso = event.isoValue;
_ev = _ev + log2(event.isoValue.value / _iso.value);
_iso = event.isoValue;
@ -130,14 +150,16 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
void _emitMeasuredState(Emitter emit) {
emit(_isMeteringInProgress
? MeteringInProgressState(
iso: _iso,
ev: _ev,
film: _film,
iso: _iso,
nd: _nd,
exposurePairs: _buildExposureValues(_ev),
)
: MeteringEndedState(
iso: _iso,
ev: _ev,
film: _film,
iso: _iso,
nd: _nd,
exposurePairs: _buildExposureValues(_ev),
));
@ -188,7 +210,7 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
itemsCount,
(index) => ExposurePair(
_apertureValues[index + apertureOffset],
_shutterSpeedValues[index + shutterSpeedOffset],
_film.reciprocityFailure(_shutterSpeedValues[index + shutterSpeedOffset]),
),
growable: false,
);

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:lightmeter/data/models/exposure_pair.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/interactors/metering_interactor.dart';
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
@ -11,8 +12,10 @@ import 'widget_container_camera.dart';
class CameraContainerProvider extends StatelessWidget {
final ExposurePair? fastest;
final ExposurePair? slowest;
final Film film;
final IsoValue iso;
final NdValue nd;
final ValueChanged<Film> onFilmChanged;
final ValueChanged<IsoValue> onIsoChanged;
final ValueChanged<NdValue> onNdChanged;
final List<ExposurePair> exposurePairs;
@ -20,8 +23,10 @@ class CameraContainerProvider extends StatelessWidget {
const CameraContainerProvider({
required this.fastest,
required this.slowest,
required this.film,
required this.iso,
required this.nd,
required this.onFilmChanged,
required this.onIsoChanged,
required this.onNdChanged,
required this.exposurePairs,
@ -39,8 +44,10 @@ class CameraContainerProvider extends StatelessWidget {
child: CameraContainer(
fastest: fastest,
slowest: slowest,
film: film,
iso: iso,
nd: nd,
onFilmChanged: onFilmChanged,
onIsoChanged: onIsoChanged,
onNdChanged: onNdChanged,
exposurePairs: exposurePairs,

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:lightmeter/data/models/exposure_pair.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/features.dart';
import 'package:lightmeter/platform_config.dart';
import 'package:lightmeter/res/dimens.dart';
@ -21,8 +22,10 @@ import 'state_container_camera.dart';
class CameraContainer extends StatelessWidget {
final ExposurePair? fastest;
final ExposurePair? slowest;
final Film film;
final IsoValue iso;
final NdValue nd;
final ValueChanged<Film> onFilmChanged;
final ValueChanged<IsoValue> onIsoChanged;
final ValueChanged<NdValue> onNdChanged;
final List<ExposurePair> exposurePairs;
@ -30,8 +33,10 @@ class CameraContainer extends StatelessWidget {
const CameraContainer({
required this.fastest,
required this.slowest,
required this.film,
required this.iso,
required this.nd,
required this.onFilmChanged,
required this.onIsoChanged,
required this.onNdChanged,
required this.exposurePairs,
@ -56,8 +61,10 @@ class CameraContainer extends StatelessWidget {
readingsContainer: ReadingsContainer(
fastest: fastest,
slowest: slowest,
film: film,
iso: iso,
nd: nd,
onFilmChanged: onFilmChanged,
onIsoChanged: onIsoChanged,
onNdChanged: onNdChanged,
),

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:lightmeter/data/models/exposure_pair.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/interactors/metering_interactor.dart';
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
@ -11,8 +12,10 @@ import 'widget_container_light_sensor.dart';
class LightSensorContainerProvider extends StatelessWidget {
final ExposurePair? fastest;
final ExposurePair? slowest;
final Film film;
final IsoValue iso;
final NdValue nd;
final ValueChanged<Film> onFilmChanged;
final ValueChanged<IsoValue> onIsoChanged;
final ValueChanged<NdValue> onNdChanged;
final List<ExposurePair> exposurePairs;
@ -20,8 +23,10 @@ class LightSensorContainerProvider extends StatelessWidget {
const LightSensorContainerProvider({
required this.fastest,
required this.slowest,
required this.film,
required this.iso,
required this.nd,
required this.onFilmChanged,
required this.onIsoChanged,
required this.onNdChanged,
required this.exposurePairs,
@ -39,8 +44,10 @@ class LightSensorContainerProvider extends StatelessWidget {
child: LightSensorContainer(
fastest: fastest,
slowest: slowest,
film: film,
iso: iso,
nd: nd,
onFilmChanged: onFilmChanged,
onIsoChanged: onIsoChanged,
onNdChanged: onNdChanged,
exposurePairs: exposurePairs,

View file

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:lightmeter/data/models/exposure_pair.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/res/dimens.dart';
import 'package:lightmeter/screens/metering/components/shared/exposure_pairs_list/widget_list_exposure_pairs.dart';
import 'package:lightmeter/screens/metering/components/shared/metering_top_bar/widget_top_bar_metering.dart';
@ -9,8 +10,10 @@ import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
class LightSensorContainer extends StatelessWidget {
final ExposurePair? fastest;
final ExposurePair? slowest;
final Film film;
final IsoValue iso;
final NdValue nd;
final ValueChanged<Film> onFilmChanged;
final ValueChanged<IsoValue> onIsoChanged;
final ValueChanged<NdValue> onNdChanged;
final List<ExposurePair> exposurePairs;
@ -18,8 +21,10 @@ class LightSensorContainer extends StatelessWidget {
const LightSensorContainer({
required this.fastest,
required this.slowest,
required this.film,
required this.iso,
required this.nd,
required this.onFilmChanged,
required this.onIsoChanged,
required this.onNdChanged,
required this.exposurePairs,
@ -34,8 +39,10 @@ class LightSensorContainer extends StatelessWidget {
readingsContainer: ReadingsContainer(
fastest: fastest,
slowest: slowest,
film: film,
iso: iso,
nd: nd,
onFilmChanged: onFilmChanged,
onIsoChanged: onIsoChanged,
onNdChanged: onNdChanged,
),

View file

@ -4,7 +4,6 @@ import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/features.dart';
import 'package:lightmeter/generated/l10n.dart';
import 'package:lightmeter/providers/equipment_profile_provider.dart';
import 'package:lightmeter/providers/film_profile.dart';
import 'package:lightmeter/res/dimens.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
@ -15,16 +14,20 @@ import 'components/reading_value_container/widget_container_reading_value.dart';
class ReadingsContainer extends StatelessWidget {
final ExposurePair? fastest;
final ExposurePair? slowest;
final Film film;
final IsoValue iso;
final NdValue nd;
final ValueChanged<Film> onFilmChanged;
final ValueChanged<IsoValue> onIsoChanged;
final ValueChanged<NdValue> onNdChanged;
const ReadingsContainer({
required this.fastest,
required this.slowest,
required this.film,
required this.iso,
required this.nd,
required this.onFilmChanged,
required this.onIsoChanged,
required this.onNdChanged,
super.key,
@ -52,7 +55,11 @@ class ReadingsContainer extends StatelessWidget {
],
),
const _InnerPadding(),
const _FilmPicker(),
_FilmPicker(
values: Film.values,
selectedValue: film,
onChanged: onFilmChanged,
),
const _InnerPadding(),
Row(
children: [
@ -106,20 +113,28 @@ class _EquipmentProfilePicker extends StatelessWidget {
}
class _FilmPicker extends StatelessWidget {
const _FilmPicker();
final List<Film> values;
final Film selectedValue;
final ValueChanged<Film> onChanged;
const _FilmPicker({
required this.values,
required this.selectedValue,
required this.onChanged,
});
@override
Widget build(BuildContext context) {
return AnimatedDialogPicker<FilmData>(
return AnimatedDialogPicker<Film>(
title: S.of(context).film,
selectedValue: Film.of(context),
values: FilmData.values,
selectedValue: selectedValue,
values: values,
itemTitleBuilder: (_, value) => Text(value.name.isEmpty ? S.of(context).none : value.name),
onChanged: FilmProvider.of(context).setFilm,
onChanged: onChanged,
closedChild: ReadingValueContainer.singleValue(
value: ReadingValue(
label: S.of(context).film,
value: Film.of(context).name.isEmpty ? S.of(context).none : Film.of(context).name,
value: selectedValue.name.isEmpty ? S.of(context).none : selectedValue.name,
),
),
);

View file

@ -1,3 +1,4 @@
import 'package:lightmeter/data/models/film.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
abstract class MeteringEvent {
@ -16,6 +17,12 @@ class EquipmentProfileChangedEvent extends MeteringEvent {
const EquipmentProfileChangedEvent(this.equipmentProfileData);
}
class FilmChangedEvent extends MeteringEvent {
final Film data;
const FilmChangedEvent(this.data);
}
class IsoChangedEvent extends MeteringEvent {
final IsoValue isoValue;

View file

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:lightmeter/data/models/ev_source_type.dart';
import 'package:lightmeter/data/models/exposure_pair.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/environment.dart';
import 'package:lightmeter/providers/equipment_profile_provider.dart';
import 'package:lightmeter/providers/ev_source_type_provider.dart';
@ -44,8 +45,10 @@ class _MeteringScreenState extends State<MeteringScreen> {
? _MeteringContainerBuidler(
fastest: state.fastest,
slowest: state.slowest,
film: state.film,
iso: state.iso,
nd: state.nd,
onFilmChanged: (value) => _bloc.add(FilmChangedEvent(value)),
onIsoChanged: (value) => _bloc.add(IsoChangedEvent(value)),
onNdChanged: (value) => _bloc.add(NdChangedEvent(value)),
exposurePairs: state.exposurePairs,
@ -73,8 +76,10 @@ class _MeteringScreenState extends State<MeteringScreen> {
class _MeteringContainerBuidler extends StatelessWidget {
final ExposurePair? fastest;
final ExposurePair? slowest;
final Film film;
final IsoValue iso;
final NdValue nd;
final ValueChanged<Film> onFilmChanged;
final ValueChanged<IsoValue> onIsoChanged;
final ValueChanged<NdValue> onNdChanged;
final List<ExposurePair> exposurePairs;
@ -82,8 +87,10 @@ class _MeteringContainerBuidler extends StatelessWidget {
const _MeteringContainerBuidler({
required this.fastest,
required this.slowest,
required this.film,
required this.iso,
required this.nd,
required this.onFilmChanged,
required this.onIsoChanged,
required this.onNdChanged,
required this.exposurePairs,
@ -95,8 +102,10 @@ class _MeteringContainerBuidler extends StatelessWidget {
? CameraContainerProvider(
fastest: fastest,
slowest: slowest,
film: film,
iso: iso,
nd: nd,
onFilmChanged: onFilmChanged,
onIsoChanged: onIsoChanged,
onNdChanged: onNdChanged,
exposurePairs: exposurePairs,
@ -104,8 +113,10 @@ class _MeteringContainerBuidler extends StatelessWidget {
: LightSensorContainerProvider(
fastest: fastest,
slowest: slowest,
film: film,
iso: iso,
nd: nd,
onFilmChanged: onFilmChanged,
onIsoChanged: onIsoChanged,
onNdChanged: onNdChanged,
exposurePairs: exposurePairs,

View file

@ -1,6 +1,9 @@
import 'package:flutter/material.dart';
import 'package:lightmeter/data/models/exposure_pair.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
@immutable
abstract class MeteringState {
const MeteringState();
}
@ -11,12 +14,14 @@ class LoadingState extends MeteringState {
abstract class MeteringDataState extends MeteringState {
final double ev;
final Film film;
final IsoValue iso;
final NdValue nd;
final List<ExposurePair> exposurePairs;
const MeteringDataState({
required this.ev,
required this.film,
required this.iso,
required this.nd,
required this.exposurePairs,
@ -27,8 +32,9 @@ abstract class MeteringDataState extends MeteringState {
}
class MeteringInProgressState extends MeteringDataState {
MeteringInProgressState({
const MeteringInProgressState({
required super.ev,
required super.film,
required super.iso,
required super.nd,
required super.exposurePairs,
@ -36,8 +42,9 @@ class MeteringInProgressState extends MeteringDataState {
}
class MeteringEndedState extends MeteringDataState {
MeteringEndedState({
const MeteringEndedState({
required super.ev,
required super.film,
required super.iso,
required super.nd,
required super.exposurePairs,