mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-23 16:00:41 +00:00
added calibration for light sensor
This commit is contained in:
parent
c777bdb68e
commit
2dc96e5c17
16 changed files with 95 additions and 29 deletions
|
@ -11,6 +11,7 @@ class UserPreferencesService {
|
||||||
|
|
||||||
static const _evSourceTypeKey = "evSourceType";
|
static const _evSourceTypeKey = "evSourceType";
|
||||||
static const _cameraEvCalibrationKey = "cameraEvCalibration";
|
static const _cameraEvCalibrationKey = "cameraEvCalibration";
|
||||||
|
static const _lightSensorEvCalibrationKey = "lightSensorEvCalibration";
|
||||||
|
|
||||||
static const _hapticsKey = "haptics";
|
static const _hapticsKey = "haptics";
|
||||||
static const _themeTypeKey = "themeType";
|
static const _themeTypeKey = "themeType";
|
||||||
|
@ -35,6 +36,9 @@ class UserPreferencesService {
|
||||||
double get cameraEvCalibration => _sharedPreferences.getDouble(_cameraEvCalibrationKey) ?? 0.0;
|
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);
|
||||||
|
|
||||||
ThemeType get themeType => ThemeType.values[_sharedPreferences.getInt(_themeTypeKey) ?? 0];
|
ThemeType get themeType => ThemeType.values[_sharedPreferences.getInt(_themeTypeKey) ?? 0];
|
||||||
set themeType(ThemeType value) => _sharedPreferences.setInt(_themeTypeKey, value.index);
|
set themeType(ThemeType value) => _sharedPreferences.setInt(_themeTypeKey, value.index);
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ class MeteringInteractor {
|
||||||
);
|
);
|
||||||
|
|
||||||
double get cameraEvCalibration => _userPreferencesService.cameraEvCalibration;
|
double get cameraEvCalibration => _userPreferencesService.cameraEvCalibration;
|
||||||
|
double get lightSensorEvCalibration => _userPreferencesService.lightSensorEvCalibration;
|
||||||
|
|
||||||
bool get isHapticsEnabled => _userPreferencesService.haptics;
|
bool get isHapticsEnabled => _userPreferencesService.haptics;
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,9 @@ class SettingsInteractor {
|
||||||
double get cameraEvCalibration => _userPreferencesService.cameraEvCalibration;
|
double get cameraEvCalibration => _userPreferencesService.cameraEvCalibration;
|
||||||
void setCameraEvCalibration(double value) => _userPreferencesService.cameraEvCalibration = value;
|
void setCameraEvCalibration(double value) => _userPreferencesService.cameraEvCalibration = value;
|
||||||
|
|
||||||
|
double get lightSensorEvCalibration => _userPreferencesService.lightSensorEvCalibration;
|
||||||
|
void setLightSensorEvCalibration(double value) => _userPreferencesService.lightSensorEvCalibration = value;
|
||||||
|
|
||||||
bool get isHapticsEnabled => _userPreferencesService.haptics;
|
bool get isHapticsEnabled => _userPreferencesService.haptics;
|
||||||
|
|
||||||
/// Executes vibration if haptics are enabled in settings
|
/// Executes vibration if haptics are enabled in settings
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
"calibration": "Calibration",
|
"calibration": "Calibration",
|
||||||
"calibrationMessage": "The accuracy of the readings measured by this application depends entirely on the hardware of the device. Therefore, consider testing this application and setting up an EV calibration value that will give you the desired measurement results.",
|
"calibrationMessage": "The accuracy of the readings measured by this application depends entirely on the hardware 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",
|
"camera": "Camera",
|
||||||
|
"lightSensor": "Light sensor",
|
||||||
"general": "General",
|
"general": "General",
|
||||||
"haptics": "Haptics",
|
"haptics": "Haptics",
|
||||||
"theme": "Theme",
|
"theme": "Theme",
|
||||||
|
|
|
@ -6,7 +6,9 @@ import 'state_communication_metering.dart';
|
||||||
class MeteringCommunicationBloc
|
class MeteringCommunicationBloc
|
||||||
extends Bloc<MeteringCommunicationEvent, MeteringCommunicationState> {
|
extends Bloc<MeteringCommunicationEvent, MeteringCommunicationState> {
|
||||||
MeteringCommunicationBloc() : super(const InitState()) {
|
MeteringCommunicationBloc() : super(const InitState()) {
|
||||||
on<MeasureEvent>((_, emit) => emit(const MeasureState()));
|
// `MeasureState` is not const, so that `Bloc` treats each state as new and updates state stream
|
||||||
|
// ignore: prefer_const_constructors
|
||||||
|
on<MeasureEvent>((_, emit) => emit(MeasureState()));
|
||||||
on<MeasuredEvent>((event, emit) => emit(MeasuredState(event.ev100)));
|
on<MeasuredEvent>((event, emit) => emit(MeasuredState(event.ev100)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:lightmeter/data/models/ev_source_type.dart';
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
import 'package:lightmeter/res/dimens.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import 'components/widget_button_measure.dart';
|
import 'components/widget_button_measure.dart';
|
||||||
import 'components/widget_button_secondary.dart';
|
import 'components/widget_button_secondary.dart';
|
||||||
|
@ -36,7 +38,9 @@ class MeteringBottomControls extends StatelessWidget {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: MeteringSecondaryButton(
|
child: MeteringSecondaryButton(
|
||||||
onPressed: onSwitchEvSourceType!,
|
onPressed: onSwitchEvSourceType!,
|
||||||
icon: Icons.sync,
|
icon: context.watch<EvSourceType>() != EvSourceType.camera
|
||||||
|
? Icons.camera_rear
|
||||||
|
: Icons.wb_incandescent,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
|
|
|
@ -34,8 +34,8 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
|
||||||
double _currentExposureOffset = 0.0;
|
double _currentExposureOffset = 0.0;
|
||||||
|
|
||||||
CameraContainerBloc(
|
CameraContainerBloc(
|
||||||
MeteringCommunicationBloc communicationBloc,
|
|
||||||
this._meteringInteractor,
|
this._meteringInteractor,
|
||||||
|
MeteringCommunicationBloc communicationBloc,
|
||||||
) : super(
|
) : super(
|
||||||
communicationBloc,
|
communicationBloc,
|
||||||
const CameraInitState(),
|
const CameraInitState(),
|
||||||
|
|
|
@ -33,8 +33,8 @@ class CameraContainerProvider extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => CameraContainerBloc(
|
create: (context) => CameraContainerBloc(
|
||||||
context.read<MeteringCommunicationBloc>(),
|
|
||||||
context.read<MeteringInteractor>(),
|
context.read<MeteringInteractor>(),
|
||||||
|
context.read<MeteringCommunicationBloc>(),
|
||||||
),
|
),
|
||||||
child: CameraContainer(
|
child: CameraContainer(
|
||||||
fastest: fastest,
|
fastest: fastest,
|
||||||
|
|
|
@ -15,7 +15,6 @@ import 'components/camera_controls/widget_camera_controls.dart';
|
||||||
import 'event_container_camera.dart';
|
import 'event_container_camera.dart';
|
||||||
import 'state_container_camera.dart';
|
import 'state_container_camera.dart';
|
||||||
|
|
||||||
// TODO: add stepHeight calculation based on Text
|
|
||||||
class CameraContainer extends StatelessWidget {
|
class CameraContainer extends StatelessWidget {
|
||||||
final ExposurePair? fastest;
|
final ExposurePair? fastest;
|
||||||
final ExposurePair? slowest;
|
final ExposurePair? slowest;
|
||||||
|
|
|
@ -18,8 +18,8 @@ class LightSensorContainerBloc
|
||||||
StreamSubscription<int>? _luxSubscriptions;
|
StreamSubscription<int>? _luxSubscriptions;
|
||||||
|
|
||||||
LightSensorContainerBloc(
|
LightSensorContainerBloc(
|
||||||
MeteringCommunicationBloc communicationBloc,
|
|
||||||
this._meteringInteractor,
|
this._meteringInteractor,
|
||||||
|
MeteringCommunicationBloc communicationBloc,
|
||||||
) : super(
|
) : super(
|
||||||
communicationBloc,
|
communicationBloc,
|
||||||
const LightSensorInitState(),
|
const LightSensorInitState(),
|
||||||
|
@ -30,7 +30,9 @@ class LightSensorContainerBloc
|
||||||
if (communicationState is communication_states.MeasureState) {
|
if (communicationState is communication_states.MeasureState) {
|
||||||
if (_luxSubscriptions == null) {
|
if (_luxSubscriptions == null) {
|
||||||
_luxSubscriptions = _meteringInteractor.luxStream().listen((event) {
|
_luxSubscriptions = _meteringInteractor.luxStream().listen((event) {
|
||||||
communicationBloc.add(communication_event.MeasuredEvent(log2(event.toDouble() / 2.5)));
|
communicationBloc.add(communication_event.MeasuredEvent(
|
||||||
|
log2(event.toDouble() / 2.5) + _meteringInteractor.lightSensorEvCalibration,
|
||||||
|
));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
_luxSubscriptions?.cancel().then((_) => _luxSubscriptions = null);
|
_luxSubscriptions?.cancel().then((_) => _luxSubscriptions = null);
|
||||||
|
|
|
@ -32,9 +32,10 @@ class LightSensorContainerProvider extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
|
lazy: false,
|
||||||
create: (context) => LightSensorContainerBloc(
|
create: (context) => LightSensorContainerBloc(
|
||||||
context.read<MeteringCommunicationBloc>(),
|
|
||||||
context.read<MeteringInteractor>(),
|
context.read<MeteringInteractor>(),
|
||||||
|
context.read<MeteringCommunicationBloc>(),
|
||||||
),
|
),
|
||||||
child: LightSensorContainer(
|
child: LightSensorContainer(
|
||||||
fastest: fastest,
|
fastest: fastest,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
|
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
|
||||||
|
|
|
@ -8,26 +8,47 @@ class CalibrationDialogBloc extends Bloc<CalibrationDialogEvent, CalibrationDial
|
||||||
final SettingsInteractor _settingsInteractor;
|
final SettingsInteractor _settingsInteractor;
|
||||||
|
|
||||||
late double _cameraEvCalibration = _settingsInteractor.cameraEvCalibration;
|
late double _cameraEvCalibration = _settingsInteractor.cameraEvCalibration;
|
||||||
|
late double _lightSensorEvCalibration = _settingsInteractor.lightSensorEvCalibration;
|
||||||
|
|
||||||
CalibrationDialogBloc(this._settingsInteractor)
|
CalibrationDialogBloc(this._settingsInteractor)
|
||||||
: super(CalibrationDialogState(_settingsInteractor.cameraEvCalibration)) {
|
: super(
|
||||||
|
CalibrationDialogState(
|
||||||
|
_settingsInteractor.cameraEvCalibration,
|
||||||
|
_settingsInteractor.lightSensorEvCalibration,
|
||||||
|
),
|
||||||
|
) {
|
||||||
on<CameraEvCalibrationChangedEvent>(_onCameraEvCalibrationChanged);
|
on<CameraEvCalibrationChangedEvent>(_onCameraEvCalibrationChanged);
|
||||||
on<CameraEvCalibrationResetEvent>(_onCameraEvCalibrationReset);
|
on<CameraEvCalibrationResetEvent>(_onCameraEvCalibrationReset);
|
||||||
|
on<LightSensorEvCalibrationChangedEvent>(_onLightSensorEvCalibrationChanged);
|
||||||
|
on<LightSensorEvCalibrationResetEvent>(_onLightSensorEvCalibrationReset);
|
||||||
on<SaveCalibrationDialogEvent>(_onSaveCalibration);
|
on<SaveCalibrationDialogEvent>(_onSaveCalibration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onCameraEvCalibrationChanged(CameraEvCalibrationChangedEvent event, Emitter emit) {
|
void _onCameraEvCalibrationChanged(CameraEvCalibrationChangedEvent event, Emitter emit) {
|
||||||
_cameraEvCalibration = event.value;
|
_cameraEvCalibration = event.value;
|
||||||
emit(CalibrationDialogState(event.value));
|
emit(CalibrationDialogState(_cameraEvCalibration, _lightSensorEvCalibration));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onCameraEvCalibrationReset(CameraEvCalibrationResetEvent event, Emitter emit) {
|
void _onCameraEvCalibrationReset(CameraEvCalibrationResetEvent event, Emitter emit) {
|
||||||
_settingsInteractor.quickVibration();
|
_settingsInteractor.quickVibration();
|
||||||
_cameraEvCalibration = 0;
|
_cameraEvCalibration = 0;
|
||||||
emit(CalibrationDialogState(_cameraEvCalibration));
|
emit(CalibrationDialogState(_cameraEvCalibration, _lightSensorEvCalibration));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onLightSensorEvCalibrationChanged(
|
||||||
|
LightSensorEvCalibrationChangedEvent event, Emitter emit) {
|
||||||
|
_lightSensorEvCalibration = event.value;
|
||||||
|
emit(CalibrationDialogState(_cameraEvCalibration, _lightSensorEvCalibration));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onLightSensorEvCalibrationReset(LightSensorEvCalibrationResetEvent event, Emitter emit) {
|
||||||
|
_settingsInteractor.quickVibration();
|
||||||
|
_lightSensorEvCalibration = 0;
|
||||||
|
emit(CalibrationDialogState(_cameraEvCalibration, _lightSensorEvCalibration));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onSaveCalibration(SaveCalibrationDialogEvent event, __) {
|
void _onSaveCalibration(SaveCalibrationDialogEvent event, __) {
|
||||||
_settingsInteractor.setCameraEvCalibration(_cameraEvCalibration);
|
_settingsInteractor.setCameraEvCalibration(_cameraEvCalibration);
|
||||||
|
_settingsInteractor.setLightSensorEvCalibration(_lightSensorEvCalibration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,16 @@ class CameraEvCalibrationResetEvent extends CalibrationDialogEvent {
|
||||||
const CameraEvCalibrationResetEvent();
|
const CameraEvCalibrationResetEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LightSensorEvCalibrationChangedEvent extends CalibrationDialogEvent {
|
||||||
|
final double value;
|
||||||
|
|
||||||
|
const LightSensorEvCalibrationChangedEvent(this.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
class LightSensorEvCalibrationResetEvent extends CalibrationDialogEvent {
|
||||||
|
const LightSensorEvCalibrationResetEvent();
|
||||||
|
}
|
||||||
|
|
||||||
class SaveCalibrationDialogEvent extends CalibrationDialogEvent {
|
class SaveCalibrationDialogEvent extends CalibrationDialogEvent {
|
||||||
const SaveCalibrationDialogEvent();
|
const SaveCalibrationDialogEvent();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
class CalibrationDialogState {
|
class CalibrationDialogState {
|
||||||
final double cameraEvCalibration;
|
final double cameraEvCalibration;
|
||||||
|
final double lightSensorEvCalibration;
|
||||||
|
|
||||||
const CalibrationDialogState(this.cameraEvCalibration);
|
const CalibrationDialogState(
|
||||||
|
this.cameraEvCalibration,
|
||||||
|
this.lightSensorEvCalibration,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,16 +9,9 @@ import 'package:lightmeter/utils/to_string_signed.dart';
|
||||||
import 'bloc_dialog_calibration.dart';
|
import 'bloc_dialog_calibration.dart';
|
||||||
import 'state_dialog_calibration.dart';
|
import 'state_dialog_calibration.dart';
|
||||||
|
|
||||||
class CalibrationDialog extends StatefulWidget {
|
class CalibrationDialog extends StatelessWidget {
|
||||||
const CalibrationDialog({super.key});
|
const CalibrationDialog({super.key});
|
||||||
|
|
||||||
@override
|
|
||||||
State<CalibrationDialog> createState() => _CalibrationDialogState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _CalibrationDialogState extends State<CalibrationDialog> {
|
|
||||||
CalibrationDialogBloc get bloc => context.read<CalibrationDialogBloc>();
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
|
@ -30,17 +23,39 @@ class _CalibrationDialogState extends State<CalibrationDialog> {
|
||||||
),
|
),
|
||||||
title: Text(S.of(context).calibration),
|
title: Text(S.of(context).calibration),
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: Dimens.paddingL),
|
contentPadding: const EdgeInsets.symmetric(horizontal: Dimens.paddingL),
|
||||||
content: BlocBuilder<CalibrationDialogBloc, CalibrationDialogState>(
|
content: SingleChildScrollView(
|
||||||
builder: (context, state) => Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Text(S.of(context).calibrationMessage),
|
Text(S.of(context).calibrationMessage),
|
||||||
const SizedBox(height: Dimens.grid16),
|
const SizedBox(height: Dimens.grid16),
|
||||||
_CalibrationUnit(
|
BlocBuilder<CalibrationDialogBloc, CalibrationDialogState>(
|
||||||
title: S.of(context).camera,
|
buildWhen: (previous, current) =>
|
||||||
value: state.cameraEvCalibration,
|
previous.cameraEvCalibration != current.cameraEvCalibration,
|
||||||
onChanged: (value) => bloc.add(CameraEvCalibrationChangedEvent(value)),
|
builder: (context, state) => _CalibrationUnit(
|
||||||
onReset: () => bloc.add(const CameraEvCalibrationResetEvent()),
|
title: S.of(context).camera,
|
||||||
|
value: state.cameraEvCalibration,
|
||||||
|
onChanged: (value) => context
|
||||||
|
.read<CalibrationDialogBloc>()
|
||||||
|
.add(CameraEvCalibrationChangedEvent(value)),
|
||||||
|
onReset: () => context
|
||||||
|
.read<CalibrationDialogBloc>()
|
||||||
|
.add(const CameraEvCalibrationResetEvent()),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
BlocBuilder<CalibrationDialogBloc, CalibrationDialogState>(
|
||||||
|
buildWhen: (previous, current) =>
|
||||||
|
previous.lightSensorEvCalibration != current.lightSensorEvCalibration,
|
||||||
|
builder: (context, state) => _CalibrationUnit(
|
||||||
|
title: S.of(context).lightSensor,
|
||||||
|
value: state.lightSensorEvCalibration,
|
||||||
|
onChanged: (value) => context
|
||||||
|
.read<CalibrationDialogBloc>()
|
||||||
|
.add(LightSensorEvCalibrationChangedEvent(value)),
|
||||||
|
onReset: () => context
|
||||||
|
.read<CalibrationDialogBloc>()
|
||||||
|
.add(const LightSensorEvCalibrationResetEvent()),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -58,7 +73,7 @@ class _CalibrationDialogState extends State<CalibrationDialog> {
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
bloc.add(const SaveCalibrationDialogEvent());
|
context.read<CalibrationDialogBloc>().add(const SaveCalibrationDialogEvent());
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: Text(S.of(context).save),
|
child: Text(S.of(context).save),
|
||||||
|
|
Loading…
Reference in a new issue