mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-22 15:30:59 +00:00
added film picker
This commit is contained in:
parent
0ff9249f8f
commit
d0e847d25a
7 changed files with 115 additions and 45 deletions
|
@ -7,6 +7,7 @@ import 'package:light_sensor/light_sensor.dart';
|
|||
import 'package:lightmeter/data/caffeine_service.dart';
|
||||
import 'package:lightmeter/data/haptics_service.dart';
|
||||
import 'package:lightmeter/data/models/supported_locale.dart';
|
||||
import 'package:lightmeter/providers/film_profile.dart';
|
||||
import 'package:lightmeter/providers/supported_locale_provider.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
@ -48,6 +49,7 @@ class Application extends StatelessWidget {
|
|||
Provider(create: (_) => const LightSensorService()),
|
||||
],
|
||||
child: StopTypeProvider(
|
||||
child: FilmProvider(
|
||||
child: EquipmentProfileProvider(
|
||||
child: EvSourceTypeProvider(
|
||||
child: SupportedLocaleProvider(
|
||||
|
@ -79,6 +81,7 @@ class Application extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return const SizedBox();
|
||||
|
|
|
@ -23,13 +23,13 @@ double log10polynomian(
|
|||
/// do not have any reciprocity failure information, as these films are ment to be used in cinema
|
||||
/// with appropriate light and pretty short shutter speeds.
|
||||
///
|
||||
class Film {
|
||||
class FilmData {
|
||||
final String name;
|
||||
final int iso;
|
||||
|
||||
const Film(this.name, this.iso);
|
||||
const FilmData(this.name, this.iso);
|
||||
|
||||
const Film.other()
|
||||
const FilmData.other()
|
||||
: name = 'Other',
|
||||
iso = 0;
|
||||
|
||||
|
@ -51,9 +51,8 @@ class Film {
|
|||
@protected
|
||||
double reciprocityFormula(double t) => t;
|
||||
|
||||
static const List<Film> values = [
|
||||
Film.other(),
|
||||
FomapanFilm.creative100(),
|
||||
static const List<FilmData> values = [
|
||||
FilmData.other(),
|
||||
FomapanFilm.creative100(),
|
||||
FomapanFilm.creative200(),
|
||||
FomapanFilm.action400(),
|
||||
|
@ -79,7 +78,7 @@ class Film {
|
|||
/// 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 {
|
||||
class AgfaFilm extends FilmData {
|
||||
final double a;
|
||||
final double b;
|
||||
final double c;
|
||||
|
@ -100,7 +99,7 @@ class AgfaFilm extends Film {
|
|||
double reciprocityFormula(double t) => t * log10polynomian(t, a, b, c);
|
||||
}
|
||||
|
||||
class FomapanFilm extends Film {
|
||||
class FomapanFilm extends FilmData {
|
||||
final double a;
|
||||
final double b;
|
||||
final double c;
|
||||
|
@ -127,7 +126,7 @@ class FomapanFilm extends Film {
|
|||
super('Fomapan ACTION 400', 400);
|
||||
}
|
||||
|
||||
class IlfordFilm extends Film {
|
||||
class IlfordFilm extends FilmData {
|
||||
final double reciprocityPower;
|
||||
|
||||
/// https://www.ilfordphoto.com/amfile/file/download/file/1948/product/1650/
|
||||
|
@ -189,7 +188,7 @@ class IlfordFilm extends Film {
|
|||
double reciprocityFormula(double t) => pow(t, reciprocityPower).toDouble();
|
||||
}
|
||||
|
||||
class KodakFilm extends Film {
|
||||
class KodakFilm extends FilmData {
|
||||
final double a;
|
||||
final double b;
|
||||
final double c;
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
|||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'models/ev_source_type.dart';
|
||||
import 'models/film.dart';
|
||||
import 'models/theme_type.dart';
|
||||
|
||||
class UserPreferencesService {
|
||||
|
@ -13,6 +14,7 @@ class UserPreferencesService {
|
|||
static const _evSourceTypeKey = "evSourceType";
|
||||
static const _cameraEvCalibrationKey = "cameraEvCalibration";
|
||||
static const _lightSensorEvCalibrationKey = "lightSensorEvCalibration";
|
||||
static const _filmKey = "film";
|
||||
|
||||
static const _caffeineKey = "caffeine";
|
||||
static const _hapticsKey = "haptics";
|
||||
|
@ -63,16 +65,13 @@ class UserPreferencesService {
|
|||
}
|
||||
}
|
||||
|
||||
IsoValue get iso =>
|
||||
isoValues.firstWhere((v) => v.value == (_sharedPreferences.getInt(_isoKey) ?? 100));
|
||||
IsoValue get iso => isoValues.firstWhere((v) => v.value == (_sharedPreferences.getInt(_isoKey) ?? 100));
|
||||
set iso(IsoValue value) => _sharedPreferences.setInt(_isoKey, value.value);
|
||||
|
||||
NdValue get ndFilter =>
|
||||
ndValues.firstWhere((v) => v.value == (_sharedPreferences.getInt(_ndFilterKey) ?? 0));
|
||||
NdValue get ndFilter => ndValues.firstWhere((v) => v.value == (_sharedPreferences.getInt(_ndFilterKey) ?? 0));
|
||||
set ndFilter(NdValue value) => _sharedPreferences.setInt(_ndFilterKey, value.value);
|
||||
|
||||
EvSourceType get evSourceType =>
|
||||
EvSourceType.values[_sharedPreferences.getInt(_evSourceTypeKey) ?? 0];
|
||||
EvSourceType get evSourceType => EvSourceType.values[_sharedPreferences.getInt(_evSourceTypeKey) ?? 0];
|
||||
set evSourceType(EvSourceType value) => _sharedPreferences.setInt(_evSourceTypeKey, value.index);
|
||||
|
||||
bool get caffeine => _sharedPreferences.getBool(_caffeineKey) ?? false;
|
||||
|
@ -88,13 +87,10 @@ class UserPreferencesService {
|
|||
set locale(SupportedLocale value) => _sharedPreferences.setString(_localeKey, value.toString());
|
||||
|
||||
double get cameraEvCalibration => _sharedPreferences.getDouble(_cameraEvCalibrationKey) ?? 0.0;
|
||||
set cameraEvCalibration(double value) =>
|
||||
_sharedPreferences.setDouble(_cameraEvCalibrationKey, value);
|
||||
set cameraEvCalibration(double value) => _sharedPreferences.setDouble(_cameraEvCalibrationKey, value);
|
||||
|
||||
double get lightSensorEvCalibration =>
|
||||
_sharedPreferences.getDouble(_lightSensorEvCalibrationKey) ?? 0.0;
|
||||
set lightSensorEvCalibration(double value) =>
|
||||
_sharedPreferences.setDouble(_lightSensorEvCalibrationKey, value);
|
||||
double get lightSensorEvCalibration => _sharedPreferences.getDouble(_lightSensorEvCalibrationKey) ?? 0.0;
|
||||
set lightSensorEvCalibration(double value) => _sharedPreferences.setDouble(_lightSensorEvCalibrationKey, value);
|
||||
|
||||
ThemeType get themeType => ThemeType.values[_sharedPreferences.getInt(_themeTypeKey) ?? 0];
|
||||
set themeType(ThemeType value) => _sharedPreferences.setInt(_themeTypeKey, value.index);
|
||||
|
@ -105,6 +101,12 @@ class UserPreferencesService {
|
|||
bool get dynamicColor => _sharedPreferences.getBool(_dynamicColorKey) ?? false;
|
||||
set dynamicColor(bool value) => _sharedPreferences.setBool(_dynamicColorKey, value);
|
||||
|
||||
FilmData get film => FilmData.values.firstWhere(
|
||||
(e) => e.name == _sharedPreferences.getString(_filmKey),
|
||||
orElse: () => FilmData.values.first,
|
||||
);
|
||||
set film(FilmData value) => _sharedPreferences.setString(_filmKey, value.name);
|
||||
|
||||
String get selectedEquipmentProfileId => '';
|
||||
set selectedEquipmentProfileId(String id) {}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
"calibrationMessageCameraOnly": "The accuracy of the readings measured by this application depends entirely on the rear camera of the device. Therefore, consider testing this application and setting up an EV calibration value that will give you the desired measurement results.",
|
||||
"camera": "Camera",
|
||||
"lightSensor": "Light sensor",
|
||||
"film": "Film",
|
||||
"equipment": "Equipment",
|
||||
"equipmentProfileName": "Equipment profile name",
|
||||
"equipmentProfileNameHint": "Praktica MTL5B",
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
"calibrationMessageCameraOnly": "La précision des lectures mesurées par cette application dépend entièrement de la caméra arrière de l'appareil. Par conséquent, envisagez de tester cette application et de configurer une valeur d'étalonnage EV qui vous donnera les résultats de mesure souhaités.",
|
||||
"camera": "Caméra",
|
||||
"lightSensor": "Capteur de lumière",
|
||||
"film": "Pellicule",
|
||||
"equipment": "Équipement",
|
||||
"equipmentProfileName": "Nom du profil de l'équipement",
|
||||
"equipmentProfileNameHint": "Praktica MTL5B",
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
"calibrationMessageCameraOnly": "Точность измерений данного приложения полностью зависит от точности камеры вашего устройства. Поэтому рекомендуется самостоятельно подобрать калибровочное значение, которое даст желаемый результат измерений.",
|
||||
"camera": "Камера",
|
||||
"lightSensor": "Датчик освещённости",
|
||||
"film": "Пленка",
|
||||
"equipment": "Оборудование",
|
||||
"equipmentProfileName": "Название профиля",
|
||||
"equipmentProfileNameHint": "Praktica MTL5B",
|
||||
|
|
63
lib/providers/film_profile.dart
Normal file
63
lib/providers/film_profile.dart
Normal file
|
@ -0,0 +1,63 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:lightmeter/data/models/film.dart';
|
||||
import 'package:lightmeter/data/shared_prefs_service.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class FilmProvider extends StatefulWidget {
|
||||
final Widget child;
|
||||
|
||||
const FilmProvider({required this.child, super.key});
|
||||
|
||||
static FilmProviderState of(BuildContext context) {
|
||||
return context.findAncestorStateOfType<FilmProviderState>()!;
|
||||
}
|
||||
|
||||
@override
|
||||
State<FilmProvider> createState() => FilmProviderState();
|
||||
}
|
||||
|
||||
class FilmProviderState extends State<FilmProvider> {
|
||||
late FilmData _selectedFilm;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_selectedFilm = context.read<UserPreferencesService>().film;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Film(
|
||||
data: _selectedFilm,
|
||||
child: widget.child,
|
||||
);
|
||||
}
|
||||
|
||||
void setFilm(FilmData data) {
|
||||
setState(() {
|
||||
_selectedFilm = data;
|
||||
});
|
||||
context.read<UserPreferencesService>().film = _selectedFilm;
|
||||
}
|
||||
}
|
||||
|
||||
class Film extends InheritedWidget {
|
||||
final FilmData data;
|
||||
|
||||
const Film({
|
||||
required this.data,
|
||||
required super.child,
|
||||
super.key,
|
||||
});
|
||||
|
||||
static FilmData of(BuildContext context, {bool listen = true}) {
|
||||
if (listen) {
|
||||
return context.dependOnInheritedWidgetOfExactType<Film>()!.data;
|
||||
} else {
|
||||
return context.findAncestorWidgetOfExactType<Film>()!.data;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(Film oldWidget) => true;
|
||||
}
|
Loading…
Reference in a new issue