moved Film to resources repo

This commit is contained in:
Vadim 2023-09-12 17:30:19 +02:00
parent 483453f69a
commit cd7341b51f
21 changed files with 124 additions and 587 deletions

View file

@ -19,23 +19,16 @@ class FilmsProvider extends StatefulWidget {
}
class FilmsProviderState extends State<FilmsProvider> {
late Film _selected = Film.values.first;
@override
Widget build(BuildContext context) {
return Films(
values: Film.values,
selected: _selected,
values: const [Film.other()],
selected: const Film.other(),
child: widget.child,
);
}
void setFilm(Film film) {
if (_selected != film) {
_selected = film;
setState(() {});
}
}
void setFilm(Film film) {}
void saveFilms(List<Film> films) {}
}

View file

@ -1,235 +0,0 @@
import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
double log10(double x) => log(x) / log(10);
double log10polynomian(
double x,
double a,
double b,
double c,
) =>
a * pow(log10(x), 2) + b * log10(x) + c;
typedef ReciprocityFailureBuilder = ShutterSpeedValue Function(ShutterSpeedValue shutterSpeed);
/// Only Ilford films have reciprocity formulas provided by the manufacturer:
/// https://www.ilfordphoto.com/wp/wp-content/uploads/2017/06/Reciprocity-Failure-Compensation.pdf
///
/// Reciprocity formulas for Fomapan films and Kodak films are from here:
/// https://www.flickr.com/groups/86738082@N00/discuss/72157626050157470/
///
/// Cinema films like Kodak 5222/7222 Double-X and respective CineStill films (cause they are basically a modification of Kodak)
/// 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.
///
/// Because of this: https://github.com/dart-lang/sdk/issues/38934#issuecomment-803938315
/// `super` calls are ignored in test coverage
class Film {
final String name;
final int iso;
const Film(this.name, this.iso);
const Film.other()
: name = '',
iso = 0;
@override
String toString() => name;
ShutterSpeedValue reciprocityFailure(ShutterSpeedValue shutterSpeed) {
if (shutterSpeed.isFraction) {
return shutterSpeed;
} else {
return ShutterSpeedValue(
reciprocityFormula(shutterSpeed.rawValue),
shutterSpeed.isFraction,
shutterSpeed.stopType,
);
}
}
@protected
double reciprocityFormula(double t) => t;
static const List<Film> values = [
Film.other(),
FomapanFilm.creative100(),
FomapanFilm.creative200(),
FomapanFilm.action400(),
IlfordFilm.ortho(),
IlfordFilm.delta100(),
IlfordFilm.delta400(),
IlfordFilm.delta3200(),
IlfordFilm.fp4(),
IlfordFilm.hp5(),
IlfordFilm.panf(),
IlfordFilm.sfx200(),
IlfordFilm.xp2super(),
IlfordFilm.pan100(),
IlfordFilm.pan400(),
KodakFilm.tmax100(),
KodakFilm.tmax400(),
KodakFilm.tmax3200(),
KodakFilm.trix320(),
KodakFilm.trix400(),
];
}
/// 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 Film {
// final double a;
// final double b;
// final double c;
// const AgfaFilm.apx100()
// : a = 1,
// b = 5,
// c = 2,
// super('Agfa APX 100', 100); // coverage:ignore-line
// const AgfaFilm.apx400()
// : a = 1.5,
// b = 4.5,
// c = 3,
// super('Agfa APX 400', 400); // coverage:ignore-line
// @override
// double reciprocityFormula(double t) => t * log10polynomian(t, a, b, c);
// }
class FomapanFilm extends Film {
final double a;
final double b;
final double c;
/// https://www.foma.cz/en/fomapan-100
const FomapanFilm.creative100()
: a = 1,
b = 5,
c = 2,
super('Fomapan CREATIVE 100', 100); // coverage:ignore-line
/// https://www.foma.cz/en/fomapan-200
const FomapanFilm.creative200()
: a = 1.5,
b = 4.5,
c = 3,
super('Fomapan CREATIVE 200', 200); // coverage:ignore-line
/// https://www.foma.cz/en/fomapan-100
const FomapanFilm.action400()
: a = -1.25, // coverage:ignore-line
b = 5.75,
c = 1.5,
super('Fomapan ACTION 400', 400); // coverage:ignore-line
@override
double reciprocityFormula(double t) => t * log10polynomian(t, a, b, c);
}
class IlfordFilm extends Film {
final double reciprocityPower;
/// https://www.ilfordphoto.com/amfile/file/download/file/1948/product/1650/
const IlfordFilm.ortho()
: reciprocityPower = 1.25,
super('Ilford ORTHO+', 80); // coverage:ignore-line
/// https://www.ilfordphoto.com/amfile/file/download/file/1919/product/686/
const IlfordFilm.fp4()
: reciprocityPower = 1.26,
super('Ilford FP4+', 125); // coverage:ignore-line
/// https://www.ilfordphoto.com/amfile/file/download/file/1903/product/691/
const IlfordFilm.hp5()
: reciprocityPower = 1.31,
super('Ilford HP5+', 400); // coverage:ignore-line
/// https://www.ilfordphoto.com/amfile/file/download/file/3/product/679/
const IlfordFilm.delta100()
: reciprocityPower = 1.26,
super('Ilford DELTA 100', 100); // coverage:ignore-line
/// https://www.ilfordphoto.com/amfile/file/download/file/1915/product/684/
const IlfordFilm.delta400()
: reciprocityPower = 1.41,
super('Ilford DELTA 400', 400); // coverage:ignore-line
/// https://www.ilfordphoto.com/amfile/file/download/file/1913/product/682/
const IlfordFilm.delta3200()
: reciprocityPower = 1.33,
super('Ilford DELTA 3200', 3200); // coverage:ignore-line
/// https://www.ilfordphoto.com/amfile/file/download/file/1905/product/699/
const IlfordFilm.panf()
: reciprocityPower = 1.33,
super('Ilford Pan F+', 50); // coverage:ignore-line
/// https://www.ilfordphoto.com/amfile/file/download/file/1907/product/701/
const IlfordFilm.sfx200()
: reciprocityPower = 1.31,
super('Ilford SFX 200', 200); // coverage:ignore-line
/// https://www.ilfordphoto.com/amfile/file/download/file/1909/product/703/
const IlfordFilm.xp2super()
: reciprocityPower = 1.31,
super('Ilford XP2 SUPER', 400); // coverage:ignore-line
/// https://www.ilfordphoto.com/amfile/file/download/file/1958/product/696/
const IlfordFilm.pan100()
: reciprocityPower = 1.26,
super('Kentemere 100', 100); // coverage:ignore-line
/// https://www.ilfordphoto.com/amfile/file/download/file/1959/product/697/
const IlfordFilm.pan400()
: reciprocityPower = 1.30,
super('Kentemere 400', 400); // coverage:ignore-line
@override
double reciprocityFormula(double t) => pow(t, reciprocityPower).toDouble();
}
class KodakFilm extends Film {
final double a;
final double b;
final double c;
const KodakFilm.tmax100()
: a = 1 / 6, // coverage:ignore-line
b = 0, // coverage:ignore-line
c = 4 / 3, // coverage:ignore-line
super('Kodak T-MAX 100', 100); // coverage:ignore-line
const KodakFilm.tmax400()
: a = 2 / 3, // coverage:ignore-line
b = -1 / 2, // coverage:ignore-line
c = 4 / 3, // coverage:ignore-line
super('Kodak T-MAX 400', 400); // coverage:ignore-line
const KodakFilm.tmax3200()
: a = 7 / 6, // coverage:ignore-line
b = -1, // coverage:ignore-line
c = 4 / 3, // coverage:ignore-line
super('Kodak T-MAX 3200', 3200); // coverage:ignore-line
const KodakFilm.trix320()
: a = 2,
b = 1,
c = 2,
super('Kodak TRI-X 320', 320); // coverage:ignore-line
const KodakFilm.trix400()
: a = 2,
b = 1,
c = 2,
super('Kodak TRI-X 400', 400); // coverage:ignore-line
@override
double reciprocityFormula(double t) => t * log10polynomian(t, a, b, c);
}

View file

@ -2,7 +2,6 @@ import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:lightmeter/data/models/ev_source_type.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
import 'package:lightmeter/data/models/supported_locale.dart';
import 'package:lightmeter/data/models/theme_type.dart';
@ -19,7 +18,6 @@ class UserPreferencesService {
static const cameraEvCalibrationKey = "cameraEvCalibration";
static const lightSensorEvCalibrationKey = "lightSensorEvCalibration";
static const meteringScreenLayoutKey = "meteringScreenLayout";
static const filmKey = "film";
static const caffeineKey = "caffeine";
static const hapticsKey = "haptics";
@ -142,10 +140,4 @@ class UserPreferencesService {
bool get dynamicColor => _sharedPreferences.getBool(dynamicColorKey) ?? false;
set dynamicColor(bool value) => _sharedPreferences.setBool(dynamicColorKey, value);
Film get film => Film.values.firstWhere(
(e) => e.name == _sharedPreferences.getString(filmKey),
orElse: () => Film.values.first,
);
set film(Film value) => _sharedPreferences.setString(filmKey, value.name);
}

View file

@ -2,7 +2,6 @@ import 'package:app_settings/app_settings.dart';
import 'package:lightmeter/data/caffeine_service.dart';
import 'package:lightmeter/data/haptics_service.dart';
import 'package:lightmeter/data/light_sensor_service.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/data/models/volume_action.dart';
import 'package:lightmeter/data/permissions_service.dart';
import 'package:lightmeter/data/shared_prefs_service.dart';
@ -45,9 +44,6 @@ class MeteringInteractor {
NdValue get ndFilter => _userPreferencesService.ndFilter;
set ndFilter(NdValue value) => _userPreferencesService.ndFilter = value;
Film get film => _userPreferencesService.film;
set film(Film value) => _userPreferencesService.film = value;
VolumeAction get volumeAction => _userPreferencesService.volumeAction;
/// Executes vibration if haptics are enabled in settings

View file

@ -3,7 +3,6 @@ import 'dart:async';
import 'package:bloc_concurrency/bloc_concurrency.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/data/models/volume_action.dart';
import 'package:lightmeter/interactors/metering_interactor.dart';
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
@ -29,7 +28,6 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
) : super(
MeteringDataState(
ev100: null,
film: _meteringInteractor.film,
iso: _meteringInteractor.iso,
nd: _meteringInteractor.ndFilter,
isMetering: false,
@ -92,12 +90,9 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
/// Update selected ISO value and discard selected film, if selected equipment profile
/// doesn't contain currently selected value
IsoValue iso = state.iso;
Film film = state.film;
if (!event.equipmentProfileData.isoValues.any((v) => state.iso.value == v.value)) {
_meteringInteractor.iso = event.equipmentProfileData.isoValues.first;
iso = event.equipmentProfileData.isoValues.first;
_meteringInteractor.film = Film.values.first;
film = Film.values.first;
willUpdateMeasurements = true;
}
@ -113,7 +108,6 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
emit(
MeteringDataState(
ev100: state.ev100,
film: film,
iso: iso,
nd: nd,
isMetering: state.isMetering,
@ -123,9 +117,6 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
}
void _onFilmChanged(FilmChangedEvent event, Emitter emit) {
if (state.film.name != event.film.name) {
_meteringInteractor.film = event.film;
/// Find `IsoValue` with matching value
IsoValue iso = state.iso;
if (state.iso.value != event.film.iso && event.film != const Film.other()) {
@ -134,14 +125,12 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
orElse: () => state.iso,
);
_meteringInteractor.iso = iso;
}
/// If user selects 'Other' film we preserve currently selected ISO
/// and therefore only discard reciprocity formula
emit(
MeteringDataState(
ev100: state.ev100,
film: event.film,
iso: iso,
nd: state.nd,
isMetering: state.isMetering,
@ -151,17 +140,11 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
}
void _onIsoChanged(IsoChangedEvent event, Emitter emit) {
/// Discard currently selected film even if ISO is the same,
/// because, for example, Fomapan 400 and any Ilford 400
/// have different reciprocity formulas
_meteringInteractor.film = Film.values.first;
if (state.iso != event.isoValue) {
_meteringInteractor.iso = event.isoValue;
emit(
MeteringDataState(
ev100: state.ev100,
film: Film.values.first,
iso: event.isoValue,
nd: state.nd,
isMetering: state.isMetering,
@ -176,7 +159,6 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
emit(
MeteringDataState(
ev100: state.ev100,
film: state.film,
iso: state.iso,
nd: event.ndValue,
isMetering: state.isMetering,
@ -190,7 +172,6 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
_communicationBloc.add(const communication_events.MeasureEvent());
emit(
LoadingState(
film: state.film,
iso: state.iso,
nd: state.nd,
),
@ -209,7 +190,6 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
emit(
MeteringDataState(
ev100: event.ev100,
film: state.film,
iso: state.iso,
nd: state.nd,
isMetering: event.isMetering,
@ -221,7 +201,6 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
emit(
MeteringDataState(
ev100: null,
film: state.film,
iso: state.iso,
nd: state.nd,
isMetering: event.isMetering,

View file

@ -31,27 +31,7 @@ class _CameraPreviewState extends State<CameraPreview> {
AnimatedSwitcher(
duration: Dimens.switchDuration,
child: widget.controller != null
? ValueListenableBuilder<CameraValue>(
valueListenable: widget.controller!,
builder: (_, __, ___) => widget.controller!.value.isInitialized
? Stack(
alignment: Alignment.bottomCenter,
children: [
CameraView(controller: widget.controller!),
if (UserPreferencesProvider.meteringScreenFeatureOf(
context,
MeteringScreenLayoutFeature.histogram,
))
Positioned(
left: Dimens.grid8,
right: Dimens.grid8,
bottom: Dimens.grid16,
child: CameraHistogram(controller: widget.controller!),
),
],
)
: const SizedBox.shrink(),
)
? _CameraPreviewBuilder(controller: widget.controller!)
: CameraViewPlaceholder(error: widget.error),
),
],
@ -60,3 +40,59 @@ class _CameraPreviewState extends State<CameraPreview> {
);
}
}
class _CameraPreviewBuilder extends StatefulWidget {
final CameraController controller;
const _CameraPreviewBuilder({required this.controller});
@override
State<_CameraPreviewBuilder> createState() => _CameraPreviewBuilderState();
}
class _CameraPreviewBuilderState extends State<_CameraPreviewBuilder> {
late final ValueNotifier<bool> _initializedNotifier =
ValueNotifier<bool>(widget.controller.value.isInitialized);
@override
void initState() {
super.initState();
widget.controller.addListener(_update);
}
@override
void dispose() {
widget.controller.removeListener(_update);
_initializedNotifier.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ValueListenableBuilder<bool>(
valueListenable: _initializedNotifier,
builder: (context, value, child) => value
? Stack(
alignment: Alignment.bottomCenter,
children: [
CameraView(controller: widget.controller),
if (UserPreferencesProvider.meteringScreenFeatureOf(
context,
MeteringScreenLayoutFeature.histogram,
))
Positioned(
left: Dimens.grid8,
right: Dimens.grid8,
bottom: Dimens.grid16,
child: CameraHistogram(controller: widget.controller),
),
],
)
: const SizedBox.shrink(),
);
}
void _update() {
_initializedNotifier.value = widget.controller.value.isInitialized;
}
}

View file

@ -1,7 +1,6 @@
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/screens/metering/communication/bloc_communication_metering.dart';
import 'package:lightmeter/screens/metering/components/camera_container/bloc_container_camera.dart';
import 'package:lightmeter/screens/metering/components/camera_container/event_container_camera.dart';
@ -12,7 +11,6 @@ import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
class CameraContainerProvider extends StatelessWidget {
final ExposurePair? fastest;
final ExposurePair? slowest;
final Film film;
final IsoValue iso;
final NdValue nd;
final ValueChanged<Film> onFilmChanged;
@ -23,7 +21,6 @@ class CameraContainerProvider extends StatelessWidget {
const CameraContainerProvider({
required this.fastest,
required this.slowest,
required this.film,
required this.iso,
required this.nd,
required this.onFilmChanged,
@ -44,7 +41,6 @@ class CameraContainerProvider extends StatelessWidget {
child: CameraContainer(
fastest: fastest,
slowest: slowest,
film: film,
iso: iso,
nd: nd,
onFilmChanged: onFilmChanged,

View file

@ -3,7 +3,6 @@ import 'dart:math';
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/data/models/metering_screen_layout_config.dart';
import 'package:lightmeter/platform_config.dart';
import 'package:lightmeter/providers/user_preferences_provider.dart';
@ -23,7 +22,6 @@ import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
class CameraContainer extends StatelessWidget {
final ExposurePair? fastest;
final ExposurePair? slowest;
final Film film;
final IsoValue iso;
final NdValue nd;
final ValueChanged<Film> onFilmChanged;
@ -34,7 +32,6 @@ class CameraContainer extends StatelessWidget {
const CameraContainer({
required this.fastest,
required this.slowest,
required this.film,
required this.iso,
required this.nd,
required this.onFilmChanged,
@ -60,7 +57,6 @@ class CameraContainer extends StatelessWidget {
readingsContainer: ReadingsContainer(
fastest: fastest,
slowest: slowest,
film: film,
iso: iso,
nd: nd,
onFilmChanged: onFilmChanged,

View file

@ -1,7 +1,6 @@
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/screens/metering/communication/bloc_communication_metering.dart';
import 'package:lightmeter/screens/metering/components/light_sensor_container/bloc_container_light_sensor.dart';
import 'package:lightmeter/screens/metering/components/light_sensor_container/widget_container_light_sensor.dart';
@ -11,7 +10,6 @@ import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
class LightSensorContainerProvider extends StatelessWidget {
final ExposurePair? fastest;
final ExposurePair? slowest;
final Film film;
final IsoValue iso;
final NdValue nd;
final ValueChanged<Film> onFilmChanged;
@ -22,7 +20,6 @@ class LightSensorContainerProvider extends StatelessWidget {
const LightSensorContainerProvider({
required this.fastest,
required this.slowest,
required this.film,
required this.iso,
required this.nd,
required this.onFilmChanged,
@ -43,7 +40,6 @@ class LightSensorContainerProvider extends StatelessWidget {
child: LightSensorContainer(
fastest: fastest,
slowest: slowest,
film: film,
iso: iso,
nd: nd,
onFilmChanged: onFilmChanged,

View file

@ -1,6 +1,5 @@
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';
@ -10,7 +9,6 @@ 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;
@ -21,7 +19,6 @@ class LightSensorContainer extends StatelessWidget {
const LightSensorContainer({
required this.fastest,
required this.slowest,
required this.film,
required this.iso,
required this.nd,
required this.onFilmChanged,
@ -39,7 +36,6 @@ class LightSensorContainer extends StatelessWidget {
readingsContainer: ReadingsContainer(
fastest: fastest,
slowest: slowest,
film: film,
iso: iso,
nd: nd,
onFilmChanged: onFilmChanged,

View file

@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:lightmeter/data/models/exposure_pair.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
import 'package:lightmeter/generated/l10n.dart';
import 'package:lightmeter/providers/user_preferences_provider.dart';
@ -13,7 +12,6 @@ import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
class ReadingsContainer extends StatelessWidget {
final ExposurePair? fastest;
final ExposurePair? slowest;
final Film film;
final IsoValue iso;
final NdValue nd;
final ValueChanged<Film> onFilmChanged;
@ -23,7 +21,6 @@ class ReadingsContainer extends StatelessWidget {
const ReadingsContainer({
required this.fastest,
required this.slowest,
required this.film,
required this.iso,
required this.nd,
required this.onFilmChanged,
@ -66,11 +63,7 @@ class ReadingsContainer extends StatelessWidget {
context,
MeteringScreenLayoutFeature.filmPicker,
)) ...[
_FilmPicker(
values: Film.values,
selectedValue: film,
onChanged: onFilmChanged,
),
const _FilmPicker(),
const _InnerPadding(),
],
Row(
@ -126,29 +119,23 @@ class _EquipmentProfilePicker extends StatelessWidget {
}
class _FilmPicker extends StatelessWidget {
final List<Film> values;
final Film selectedValue;
final ValueChanged<Film> onChanged;
const _FilmPicker({
required this.values,
required this.selectedValue,
required this.onChanged,
});
const _FilmPicker();
@override
Widget build(BuildContext context) {
return AnimatedDialogPicker<Film>(
icon: Icons.camera_roll,
title: S.of(context).film,
selectedValue: selectedValue,
values: values,
selectedValue: Films.selectedOf(context),
values: Films.of(context),
itemTitleBuilder: (_, value) => Text(value.name.isEmpty ? S.of(context).none : value.name),
onChanged: onChanged,
onChanged: FilmsProvider.of(context).setFilm,
closedChild: ReadingValueContainer.singleValue(
value: ReadingValue(
label: S.of(context).film,
value: selectedValue.name.isEmpty ? S.of(context).none : selectedValue.name,
value: Films.selectedOf(context).name.isEmpty
? S.of(context).none
: Films.selectedOf(context).name,
),
),
);

View file

@ -1,4 +1,3 @@
import 'package:lightmeter/data/models/film.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
sealed class MeteringEvent {

View file

@ -4,7 +4,6 @@ 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/data/models/metering_screen_layout_config.dart';
import 'package:lightmeter/providers/services_provider.dart';
import 'package:lightmeter/providers/user_preferences_provider.dart';
@ -14,6 +13,7 @@ import 'package:lightmeter/screens/metering/components/camera_container/provider
import 'package:lightmeter/screens/metering/components/light_sensor_container/provider_container_light_sensor.dart';
import 'package:lightmeter/screens/metering/event_metering.dart';
import 'package:lightmeter/screens/metering/state_metering.dart';
import 'package:lightmeter/screens/metering/utils/film_listener.dart';
import 'package:lightmeter/screens/metering/utils/listener_metering_layout_feature.dart';
import 'package:lightmeter/screens/metering/utils/listsner_equipment_profiles.dart';
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
@ -33,7 +33,6 @@ class MeteringScreen extends StatelessWidget {
child: BlocBuilder<MeteringBloc, MeteringState>(
builder: (_, state) => MeteringContainerBuidler(
ev: state is MeteringDataState ? state.ev : null,
film: state.film,
iso: state.iso,
nd: state.nd,
onFilmChanged: (value) =>
@ -73,7 +72,11 @@ class _InheritedListeners extends StatelessWidget {
@override
Widget build(BuildContext context) {
return EquipmentProfileListener(
return FilmListener(
onDidChangeDependencies: (value) {
context.read<MeteringBloc>().add(FilmChangedEvent(value));
},
child: EquipmentProfileListener(
onDidChangeDependencies: (value) {
context.read<MeteringBloc>().add(EquipmentProfileChangedEvent(value));
},
@ -81,18 +84,18 @@ class _InheritedListeners extends StatelessWidget {
feature: MeteringScreenLayoutFeature.filmPicker,
onDidChangeDependencies: (value) {
if (!value) {
context.read<MeteringBloc>().add(const FilmChangedEvent(Film.other()));
FilmsProvider.of(context).setFilm(const Film.other());
}
},
child: child,
),
),
);
}
}
class MeteringContainerBuidler extends StatelessWidget {
final double? ev;
final Film film;
final IsoValue iso;
final NdValue nd;
final ValueChanged<Film> onFilmChanged;
@ -101,7 +104,6 @@ class MeteringContainerBuidler extends StatelessWidget {
const MeteringContainerBuidler({
required this.ev,
required this.film,
required this.iso,
required this.nd,
required this.onFilmChanged,
@ -116,7 +118,7 @@ class MeteringContainerBuidler extends StatelessWidget {
ev!,
UserPreferencesProvider.stopTypeOf(context),
EquipmentProfiles.selectedOf(context),
film,
Films.selectedOf(context),
)
: <ExposurePair>[];
final fastest = exposurePairs.isNotEmpty ? exposurePairs.first : null;
@ -126,7 +128,6 @@ class MeteringContainerBuidler extends StatelessWidget {
? CameraContainerProvider(
fastest: fastest,
slowest: slowest,
film: film,
iso: iso,
nd: nd,
onFilmChanged: onFilmChanged,
@ -137,7 +138,6 @@ class MeteringContainerBuidler extends StatelessWidget {
: LightSensorContainerProvider(
fastest: fastest,
slowest: slowest,
film: film,
iso: iso,
nd: nd,
onFilmChanged: onFilmChanged,

View file

@ -1,18 +1,15 @@
import 'package:flutter/material.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
@immutable
abstract class MeteringState {
final double? ev100;
final Film film;
final IsoValue iso;
final NdValue nd;
final bool isMetering;
const MeteringState({
this.ev100,
required this.film,
required this.iso,
required this.nd,
required this.isMetering,
@ -21,7 +18,6 @@ abstract class MeteringState {
class LoadingState extends MeteringState {
const LoadingState({
required super.film,
required super.iso,
required super.nd,
}) : super(isMetering: true);
@ -30,7 +26,6 @@ class LoadingState extends MeteringState {
class MeteringDataState extends MeteringState {
const MeteringDataState({
required super.ev100,
required super.film,
required super.iso,
required super.nd,
required super.isMetering,

View file

@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
class FilmListener extends StatefulWidget {
final ValueChanged<Film> onDidChangeDependencies;
final Widget child;
const FilmListener({
required this.onDidChangeDependencies,
required this.child,
super.key,
});
@override
State<FilmListener> createState() => _FilmListenerState();
}
class _FilmListenerState extends State<FilmListener> {
@override
void didChangeDependencies() {
super.didChangeDependencies();
widget.onDidChangeDependencies(Films.selectedOf(context));
}
@override
Widget build(BuildContext context) {
return widget.child;
}
}

View file

@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/generated/l10n.dart';
import 'package:lightmeter/screens/settings/components/shared/dialog_filter/widget_dialog_filter.dart';
import 'package:lightmeter/screens/settings/components/shared/iap_list_tile/widget_list_tile_iap.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
class FilmsListTile extends StatelessWidget {
const FilmsListTile({super.key});

View file

@ -1,121 +0,0 @@
import 'package:lightmeter/data/models/film.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
import 'package:test/test.dart';
void main() {
test('iso', () {
expect(const Film.other().iso, 0);
expect(const FomapanFilm.creative100().iso, 100);
expect(const FomapanFilm.creative200().iso, 200);
expect(const FomapanFilm.action400().iso, 400);
expect(const IlfordFilm.ortho().iso, 80);
expect(const IlfordFilm.delta100().iso, 100);
expect(const IlfordFilm.delta400().iso, 400);
expect(const IlfordFilm.delta3200().iso, 3200);
expect(const IlfordFilm.fp4().iso, 125);
expect(const IlfordFilm.hp5().iso, 400);
expect(const IlfordFilm.panf().iso, 50);
expect(const IlfordFilm.sfx200().iso, 200);
expect(const IlfordFilm.xp2super().iso, 400);
expect(const IlfordFilm.pan100().iso, 100);
expect(const IlfordFilm.pan400().iso, 400);
expect(const KodakFilm.tmax100().iso, 100);
expect(const KodakFilm.tmax400().iso, 400);
expect(const KodakFilm.tmax3200().iso, 3200);
expect(const KodakFilm.trix320().iso, 320);
expect(const KodakFilm.trix400().iso, 400);
});
test('toString()', () {
expect(const Film.other().toString(), "");
expect(const FomapanFilm.creative100().toString(), "Fomapan CREATIVE 100");
expect(const FomapanFilm.creative200().toString(), "Fomapan CREATIVE 200");
expect(const FomapanFilm.action400().toString(), "Fomapan ACTION 400");
expect(const IlfordFilm.ortho().toString(), "Ilford ORTHO+");
expect(const IlfordFilm.delta100().toString(), "Ilford DELTA 100");
expect(const IlfordFilm.delta400().toString(), "Ilford DELTA 400");
expect(const IlfordFilm.delta3200().toString(), "Ilford DELTA 3200");
expect(const IlfordFilm.fp4().toString(), "Ilford FP4+");
expect(const IlfordFilm.hp5().toString(), "Ilford HP5+");
expect(const IlfordFilm.panf().toString(), "Ilford Pan F+");
expect(const IlfordFilm.sfx200().toString(), "Ilford SFX 200");
expect(const IlfordFilm.xp2super().toString(), "Ilford XP2 SUPER");
expect(const IlfordFilm.pan100().toString(), "Kentemere 100");
expect(const IlfordFilm.pan400().toString(), "Kentemere 400");
expect(const KodakFilm.tmax100().toString(), "Kodak T-MAX 100");
expect(const KodakFilm.tmax400().toString(), "Kodak T-MAX 400");
expect(const KodakFilm.tmax3200().toString(), "Kodak T-MAX 3200");
expect(const KodakFilm.trix320().toString(), "Kodak TRI-X 320");
expect(const KodakFilm.trix400().toString(), "Kodak TRI-X 400");
});
group(
'reciprocityFailure',
() {
const inputSpeeds = [
ShutterSpeedValue(1000, true, StopType.full),
ShutterSpeedValue(1, false, StopType.full),
ShutterSpeedValue(16, false, StopType.full)
];
test('No change `Film.other()`', () {
expect(
const Film.other().reciprocityFailure(inputSpeeds[0]),
const ShutterSpeedValue(1000, true, StopType.full),
);
expect(
const Film.other().reciprocityFailure(inputSpeeds[1]),
const ShutterSpeedValue(1, false, StopType.full),
);
expect(
const Film.other().reciprocityFailure(inputSpeeds[2]),
const ShutterSpeedValue(16, false, StopType.full),
);
});
test('pow `IlfordFilm.delta100()`', () {
expect(
const IlfordFilm.delta100().reciprocityFailure(inputSpeeds[0]),
const ShutterSpeedValue(1000, true, StopType.full),
);
expect(
const IlfordFilm.delta100().reciprocityFailure(inputSpeeds[1]),
const ShutterSpeedValue(1, false, StopType.full),
);
expect(
const IlfordFilm.delta100().reciprocityFailure(inputSpeeds[2]),
const ShutterSpeedValue(32.899642452994128, false, StopType.full),
);
});
test('log10polynomian `FomapanFilm.creative100()`', () {
expect(
const FomapanFilm.creative100().reciprocityFailure(inputSpeeds[0]),
const ShutterSpeedValue(1000, true, StopType.full),
);
expect(
const FomapanFilm.creative100().reciprocityFailure(inputSpeeds[1]),
const ShutterSpeedValue(2, false, StopType.full),
);
expect(
const FomapanFilm.creative100().reciprocityFailure(inputSpeeds[2]),
const ShutterSpeedValue(151.52807753457483, false, StopType.full),
);
});
test('log10polynomian `Kodak.tmax400()`', () {
expect(
const KodakFilm.tmax400().reciprocityFailure(inputSpeeds[0]),
const ShutterSpeedValue(1000, true, StopType.full),
);
expect(
const KodakFilm.tmax400().reciprocityFailure(inputSpeeds[1]),
const ShutterSpeedValue(1.3333333333333333, false, StopType.full),
);
expect(
const KodakFilm.tmax400().reciprocityFailure(inputSpeeds[2]),
const ShutterSpeedValue(27.166026086819844, false, StopType.full),
);
});
},
);
}

View file

@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:lightmeter/data/models/ev_source_type.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
import 'package:lightmeter/data/models/supported_locale.dart';
import 'package:lightmeter/data/models/theme_type.dart';
@ -392,26 +391,4 @@ void main() {
.called(1);
});
});
group('film', () {
test('get default', () {
when(() => sharedPreferences.getString(UserPreferencesService.filmKey)).thenReturn(null);
expect(service.film, Film.values.first);
});
test('get', () {
when(() => sharedPreferences.getString(UserPreferencesService.filmKey))
.thenReturn('Fomapan ACTION 400');
expect(service.film, const FomapanFilm.action400());
});
test('set', () {
when(() => sharedPreferences.setString(UserPreferencesService.filmKey, 'Fomapan ACTION 400'))
.thenAnswer((_) => Future.value(true));
service.film = const FomapanFilm.action400();
verify(
() => sharedPreferences.setString(UserPreferencesService.filmKey, 'Fomapan ACTION 400'),
).called(1);
});
});
}

View file

@ -2,7 +2,6 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:lightmeter/data/caffeine_service.dart';
import 'package:lightmeter/data/haptics_service.dart';
import 'package:lightmeter/data/light_sensor_service.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/data/models/volume_action.dart';
import 'package:lightmeter/data/permissions_service.dart';
import 'package:lightmeter/data/shared_prefs_service.dart';
@ -124,19 +123,6 @@ void main() {
interactor.ndFilter = NdValue.values.first;
verify(() => mockUserPreferencesService.ndFilter = NdValue.values.first).called(1);
});
test('film - get', () async {
when(() => mockUserPreferencesService.film).thenReturn(Film.values.first);
expect(interactor.film, Film.values.first);
verify(() => mockUserPreferencesService.film).called(1);
});
test('film - set', () async {
when(() => mockUserPreferencesService.film = Film.values.first)
.thenReturn(Film.values.first);
interactor.film = Film.values.first;
verify(() => mockUserPreferencesService.film = Film.values.first).called(1);
});
},
);

View file

@ -1,5 +1,4 @@
import 'package:bloc_test/bloc_test.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/data/models/volume_action.dart';
import 'package:lightmeter/interactors/metering_interactor.dart';
import 'package:lightmeter/screens/metering/bloc_metering.dart';
@ -34,7 +33,6 @@ void main() {
meteringInteractor = _MockMeteringInteractor();
when<IsoValue>(() => meteringInteractor.iso).thenReturn(iso100);
when<NdValue>(() => meteringInteractor.ndFilter).thenReturn(NdValue.values.first);
when<Film>(() => meteringInteractor.film).thenReturn(Film.values.first);
when(meteringInteractor.quickVibration).thenAnswer((_) async {});
when(meteringInteractor.responseVibration).thenAnswer((_) async {});
when(meteringInteractor.errorVibration).thenAnswer((_) async {});
@ -157,7 +155,6 @@ void main() {
build: () => bloc,
seed: () => MeteringDataState(
ev100: 1.0,
film: Film.values[1],
iso: const IsoValue(100, StopType.full),
nd: NdValue.values.first,
isMetering: false,
@ -166,14 +163,12 @@ void main() {
bloc.add(const IsoChangedEvent(IsoValue(200, StopType.full)));
},
verify: (_) {
verify(() => meteringInteractor.film = Film.values.first).called(1);
verify(() => meteringInteractor.iso = const IsoValue(200, StopType.full)).called(1);
},
expect: () => [
isA<MeteringDataState>()
.having((state) => state.ev100, 'ev100', 1.0)
.having((state) => state.ev, 'ev', 2.0)
.having((state) => state.film, 'film', Film.values.first)
.having((state) => state.iso, 'iso', const IsoValue(200, StopType.full))
.having((state) => state.nd, 'nd', NdValue.values.first)
.having((state) => state.isMetering, 'isMetering', false),
@ -185,7 +180,6 @@ void main() {
build: () => bloc,
seed: () => MeteringDataState(
ev100: null,
film: Film.values[1],
iso: const IsoValue(100, StopType.full),
nd: NdValue.values.first,
isMetering: false,
@ -194,14 +188,12 @@ void main() {
bloc.add(const IsoChangedEvent(IsoValue(200, StopType.full)));
},
verify: (_) {
verify(() => meteringInteractor.film = Film.values.first).called(1);
verify(() => meteringInteractor.iso = const IsoValue(200, StopType.full)).called(1);
},
expect: () => [
isA<MeteringDataState>()
.having((state) => state.ev100, 'ev100', null)
.having((state) => state.ev, 'ev', null)
.having((state) => state.film, 'film', Film.values.first)
.having((state) => state.iso, 'iso', const IsoValue(200, StopType.full))
.having((state) => state.nd, 'nd', NdValue.values.first)
.having((state) => state.isMetering, 'isMetering', false),
@ -213,7 +205,6 @@ void main() {
build: () => bloc,
seed: () => MeteringDataState(
ev100: 1.0,
film: Film.values[1],
iso: const IsoValue(100, StopType.full),
nd: NdValue.values.first,
isMetering: false,
@ -222,7 +213,6 @@ void main() {
bloc.add(const IsoChangedEvent(IsoValue(100, StopType.full)));
},
verify: (_) {
verify(() => meteringInteractor.film = Film.values.first).called(1);
verifyNever(() => meteringInteractor.iso = const IsoValue(100, StopType.full));
},
expect: () => [],
@ -233,7 +223,6 @@ void main() {
build: () => bloc,
seed: () => MeteringDataState(
ev100: 1.0,
film: Film.values[1],
iso: const IsoValue(100, StopType.full),
nd: NdValue.values.first,
isMetering: false,
@ -244,14 +233,12 @@ void main() {
bloc.onCommunicationState(const communication_states.MeteringEndedState(2));
},
verify: (_) {
verify(() => meteringInteractor.film = Film.values.first).called(1);
verify(() => meteringInteractor.iso = const IsoValue(200, StopType.full)).called(1);
},
expect: () => [
isA<MeteringDataState>()
.having((state) => state.ev100, 'ev100', 1.0)
.having((state) => state.ev, 'ev', 2.0)
.having((state) => state.film, 'film', Film.values.first)
.having((state) => state.iso, 'iso', const IsoValue(200, StopType.full))
.having((state) => state.nd, 'nd', NdValue.values.first)
.having((state) => state.isMetering, 'isMetering', false),
@ -259,7 +246,6 @@ void main() {
isA<MeteringDataState>()
.having((state) => state.ev100, 'ev100', 2.0)
.having((state) => state.ev, 'ev', 3.0)
.having((state) => state.film, 'film', Film.values.first)
.having((state) => state.iso, 'iso', const IsoValue(200, StopType.full))
.having((state) => state.nd, 'nd', NdValue.values.first)
.having((state) => state.isMetering, 'isMetering', false),
@ -276,7 +262,6 @@ void main() {
build: () => bloc,
seed: () => MeteringDataState(
ev100: 1.0,
film: Film.values[1],
iso: const IsoValue(100, StopType.full),
nd: NdValue.values.first,
isMetering: false,
@ -291,7 +276,6 @@ void main() {
isA<MeteringDataState>()
.having((state) => state.ev100, 'ev100', 1.0)
.having((state) => state.ev, 'ev', 0.0)
.having((state) => state.film, 'film', Film.values[1])
.having((state) => state.iso, 'iso', const IsoValue(100, StopType.full))
.having((state) => state.nd, 'nd', const NdValue(2))
.having((state) => state.isMetering, 'isMetering', false),
@ -303,7 +287,6 @@ void main() {
build: () => bloc,
seed: () => MeteringDataState(
ev100: null,
film: Film.values[1],
iso: const IsoValue(100, StopType.full),
nd: NdValue.values.first,
isMetering: false,
@ -318,7 +301,6 @@ void main() {
isA<MeteringDataState>()
.having((state) => state.ev100, 'ev100', null)
.having((state) => state.ev, 'ev', null)
.having((state) => state.film, 'film', Film.values[1])
.having((state) => state.iso, 'iso', const IsoValue(100, StopType.full))
.having((state) => state.nd, 'nd', const NdValue(2))
.having((state) => state.isMetering, 'isMetering', false),
@ -330,7 +312,6 @@ void main() {
build: () => bloc,
seed: () => MeteringDataState(
ev100: 1.0,
film: Film.values[1],
iso: const IsoValue(100, StopType.full),
nd: NdValue.values.first,
isMetering: false,
@ -349,7 +330,6 @@ void main() {
build: () => bloc,
seed: () => MeteringDataState(
ev100: 1.0,
film: Film.values[1],
iso: const IsoValue(100, StopType.full),
nd: NdValue.values.first,
isMetering: false,
@ -366,7 +346,6 @@ void main() {
isA<MeteringDataState>()
.having((state) => state.ev100, 'ev100', 1.0)
.having((state) => state.ev, 'ev', 0.0)
.having((state) => state.film, 'film', Film.values[1])
.having((state) => state.iso, 'iso', const IsoValue(100, StopType.full))
.having((state) => state.nd, 'nd', const NdValue(2))
.having((state) => state.isMetering, 'isMetering', false),
@ -374,7 +353,6 @@ void main() {
isA<MeteringDataState>()
.having((state) => state.ev100, 'ev100', 2.0)
.having((state) => state.ev, 'ev', 1.0)
.having((state) => state.film, 'film', Film.values[1])
.having((state) => state.iso, 'iso', const IsoValue(100, StopType.full))
.having((state) => state.nd, 'nd', const NdValue(2))
.having((state) => state.isMetering, 'isMetering', false),
@ -391,7 +369,6 @@ void main() {
build: () => bloc,
seed: () => MeteringDataState(
ev100: 1.0,
film: const FomapanFilm.creative100(),
iso: const IsoValue(100, StopType.full),
nd: NdValue.values.first,
isMetering: false,
@ -400,14 +377,12 @@ void main() {
bloc.add(const FilmChangedEvent(FomapanFilm.creative200()));
},
verify: (_) {
verify(() => meteringInteractor.film = const FomapanFilm.creative200()).called(1);
verify(() => meteringInteractor.iso = const IsoValue(200, StopType.full)).called(1);
},
expect: () => [
isA<MeteringDataState>()
.having((state) => state.ev100, 'ev100', 1.0)
.having((state) => state.ev, 'ev', 2.0)
.having((state) => state.film, 'film', const FomapanFilm.creative200())
.having((state) => state.iso, 'iso', const IsoValue(200, StopType.full))
.having((state) => state.nd, 'nd', NdValue.values.first)
.having((state) => state.isMetering, 'isMetering', false),
@ -419,7 +394,6 @@ void main() {
build: () => bloc,
seed: () => MeteringDataState(
ev100: 1.0,
film: const FomapanFilm.creative100(),
iso: const IsoValue(100, StopType.full),
nd: NdValue.values.first,
isMetering: false,
@ -428,18 +402,9 @@ void main() {
bloc.add(const FilmChangedEvent(IlfordFilm.delta100()));
},
verify: (_) {
verify(() => meteringInteractor.film = const IlfordFilm.delta100()).called(1);
verifyNever(() => meteringInteractor.iso = const IsoValue(100, StopType.full));
},
expect: () => [
isA<MeteringDataState>()
.having((state) => state.ev100, 'ev100', 1.0)
.having((state) => state.ev, 'ev', 1.0)
.having((state) => state.film, 'film', const IlfordFilm.delta100())
.having((state) => state.iso, 'iso', const IsoValue(100, StopType.full))
.having((state) => state.nd, 'nd', NdValue.values.first)
.having((state) => state.isMetering, 'isMetering', false),
],
expect: () => [],
);
blocTest<MeteringBloc, MeteringState>(
@ -447,7 +412,6 @@ void main() {
build: () => bloc,
seed: () => MeteringDataState(
ev100: 1.0,
film: const FomapanFilm.creative100(),
iso: const IsoValue(100, StopType.full),
nd: NdValue.values.first,
isMetering: false,
@ -455,9 +419,6 @@ void main() {
act: (bloc) async {
bloc.add(const FilmChangedEvent(FomapanFilm.creative100()));
},
verify: (_) {
verifyNever(() => meteringInteractor.film = const FomapanFilm.creative100());
},
expect: () => [],
);
@ -466,7 +427,6 @@ void main() {
build: () => bloc,
seed: () => MeteringDataState(
ev100: 1.0,
film: const FomapanFilm.creative100(),
iso: const IsoValue(100, StopType.full),
nd: NdValue.values.first,
isMetering: false,
@ -475,19 +435,10 @@ void main() {
bloc.add(const FilmChangedEvent(Film.other()));
},
verify: (_) {
verify(() => meteringInteractor.film = const Film.other()).called(1);
verifyNever(() => meteringInteractor.iso = const IsoValue(0, StopType.full));
verifyNever(() => meteringInteractor.responseVibration());
},
expect: () => [
isA<MeteringDataState>()
.having((state) => state.ev100, 'ev100', 1.0)
.having((state) => state.ev, 'ev', 1.0)
.having((state) => state.film, 'film', const Film.other())
.having((state) => state.iso, 'iso', const IsoValue(100, StopType.full))
.having((state) => state.nd, 'nd', NdValue.values.first)
.having((state) => state.isMetering, 'isMetering', false),
],
expect: () => [],
);
},
);
@ -509,7 +460,6 @@ void main() {
build: () => bloc,
seed: () => MeteringDataState(
ev100: 1.0,
film: Film.values[1],
iso: const IsoValue(100, StopType.full),
nd: NdValue.values.first,
isMetering: false,
@ -518,7 +468,6 @@ void main() {
bloc.add(EquipmentProfileChangedEvent(reducedProfile));
},
verify: (_) {
verifyNever(() => meteringInteractor.film = const Film.other());
verifyNever(() => meteringInteractor.iso = reducedProfile.isoValues.first);
verifyNever(() => meteringInteractor.ndFilter = reducedProfile.ndValues.first);
verifyNever(() => meteringInteractor.responseVibration());
@ -531,7 +480,6 @@ void main() {
build: () => bloc,
seed: () => MeteringDataState(
ev100: 1.0,
film: Film.values[1],
iso: IsoValue.values[2],
nd: NdValue.values.first,
isMetering: false,
@ -540,7 +488,6 @@ void main() {
bloc.add(EquipmentProfileChangedEvent(reducedProfile));
},
verify: (_) {
verify(() => meteringInteractor.film = const Film.other()).called(1);
verify(() => meteringInteractor.iso = reducedProfile.isoValues.first).called(1);
verifyNever(() => meteringInteractor.ndFilter = reducedProfile.ndValues.first);
verify(() => meteringInteractor.responseVibration()).called(1);
@ -548,7 +495,6 @@ void main() {
expect: () => [
isA<MeteringDataState>()
.having((state) => state.ev100, 'ev100', 1.0)
.having((state) => state.film, 'film', const Film.other())
.having((state) => state.iso, 'iso', reducedProfile.isoValues.first)
.having((state) => state.nd, 'nd', NdValue.values.first)
.having((state) => state.isMetering, 'isMetering', false),
@ -560,7 +506,6 @@ void main() {
build: () => bloc,
seed: () => MeteringDataState(
ev100: 1.0,
film: Film.values[1],
iso: const IsoValue(100, StopType.full),
nd: NdValue.values[4],
isMetering: false,
@ -569,7 +514,6 @@ void main() {
bloc.add(EquipmentProfileChangedEvent(reducedProfile));
},
verify: (_) {
verifyNever(() => meteringInteractor.film = const Film.other());
verifyNever(() => meteringInteractor.iso = reducedProfile.isoValues.first);
verify(() => meteringInteractor.ndFilter = reducedProfile.ndValues.first).called(1);
verify(() => meteringInteractor.responseVibration()).called(1);
@ -577,7 +521,6 @@ void main() {
expect: () => [
isA<MeteringDataState>()
.having((state) => state.ev100, 'ev100', 1.0)
.having((state) => state.film, 'film', Film.values[1])
.having((state) => state.iso, 'iso', const IsoValue(100, StopType.full))
.having((state) => state.nd, 'nd', reducedProfile.ndValues.first)
.having((state) => state.isMetering, 'isMetering', false),
@ -589,7 +532,6 @@ void main() {
build: () => bloc,
seed: () => MeteringDataState(
ev100: 1.0,
film: Film.values[1],
iso: IsoValue.values[2],
nd: NdValue.values[4],
isMetering: false,
@ -598,7 +540,6 @@ void main() {
bloc.add(EquipmentProfileChangedEvent(reducedProfile));
},
verify: (_) {
verify(() => meteringInteractor.film = const Film.other()).called(1);
verify(() => meteringInteractor.iso = reducedProfile.isoValues.first).called(1);
verify(() => meteringInteractor.ndFilter = reducedProfile.ndValues.first).called(1);
verify(() => meteringInteractor.responseVibration()).called(1);
@ -606,7 +547,6 @@ void main() {
expect: () => [
isA<MeteringDataState>()
.having((state) => state.ev100, 'ev100', 1.0)
.having((state) => state.film, 'film', const Film.other())
.having((state) => state.iso, 'iso', reducedProfile.isoValues.first)
.having((state) => state.nd, 'nd', reducedProfile.ndValues.first)
.having((state) => state.isMetering, 'isMetering', false),

View file

@ -1,6 +1,5 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:lightmeter/data/models/exposure_pair.dart';
import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/screens/metering/screen_metering.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';