mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-26 01:10:39 +00:00
moved Film
to resources repo
This commit is contained in:
parent
483453f69a
commit
cd7341b51f
21 changed files with 124 additions and 587 deletions
|
@ -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) {}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,25 +117,20 @@ 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()) {
|
||||
iso = IsoValue.values.firstWhere(
|
||||
(e) => e.value == event.film.iso,
|
||||
orElse: () => state.iso,
|
||||
);
|
||||
_meteringInteractor.iso = iso;
|
||||
}
|
||||
/// Find `IsoValue` with matching value
|
||||
IsoValue iso = state.iso;
|
||||
if (state.iso.value != event.film.iso && event.film != const Film.other()) {
|
||||
iso = IsoValue.values.firstWhere(
|
||||
(e) => e.value == event.film.iso,
|
||||
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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:lightmeter/data/models/film.dart';
|
||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||
|
||||
sealed class MeteringEvent {
|
||||
|
|
|
@ -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,18 +72,23 @@ class _InheritedListeners extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return EquipmentProfileListener(
|
||||
return FilmListener(
|
||||
onDidChangeDependencies: (value) {
|
||||
context.read<MeteringBloc>().add(EquipmentProfileChangedEvent(value));
|
||||
context.read<MeteringBloc>().add(FilmChangedEvent(value));
|
||||
},
|
||||
child: MeteringScreenLayoutFeatureListener(
|
||||
feature: MeteringScreenLayoutFeature.filmPicker,
|
||||
child: EquipmentProfileListener(
|
||||
onDidChangeDependencies: (value) {
|
||||
if (!value) {
|
||||
context.read<MeteringBloc>().add(const FilmChangedEvent(Film.other()));
|
||||
}
|
||||
context.read<MeteringBloc>().add(EquipmentProfileChangedEvent(value));
|
||||
},
|
||||
child: child,
|
||||
child: MeteringScreenLayoutFeatureListener(
|
||||
feature: MeteringScreenLayoutFeature.filmPicker,
|
||||
onDidChangeDependencies: (value) {
|
||||
if (!value) {
|
||||
FilmsProvider.of(context).setFilm(const Film.other());
|
||||
}
|
||||
},
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -92,7 +96,6 @@ class _InheritedListeners extends StatelessWidget {
|
|||
|
||||
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,
|
||||
|
|
|
@ -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,
|
||||
|
|
30
lib/screens/metering/utils/film_listener.dart
Normal file
30
lib/screens/metering/utils/film_listener.dart
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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});
|
||||
|
|
|
@ -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),
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
Loading…
Reference in a new issue