added calibration for light sensor

This commit is contained in:
Vadim 2023-01-29 19:01:15 +03:00
parent c777bdb68e
commit 2dc96e5c17
16 changed files with 95 additions and 29 deletions

View file

@ -11,6 +11,7 @@ class UserPreferencesService {
static const _evSourceTypeKey = "evSourceType";
static const _cameraEvCalibrationKey = "cameraEvCalibration";
static const _lightSensorEvCalibrationKey = "lightSensorEvCalibration";
static const _hapticsKey = "haptics";
static const _themeTypeKey = "themeType";
@ -35,6 +36,9 @@ class UserPreferencesService {
double get cameraEvCalibration => _sharedPreferences.getDouble(_cameraEvCalibrationKey) ?? 0.0;
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];
set themeType(ThemeType value) => _sharedPreferences.setInt(_themeTypeKey, value.index);

View file

@ -16,6 +16,7 @@ class MeteringInteractor {
);
double get cameraEvCalibration => _userPreferencesService.cameraEvCalibration;
double get lightSensorEvCalibration => _userPreferencesService.lightSensorEvCalibration;
bool get isHapticsEnabled => _userPreferencesService.haptics;

View file

@ -13,6 +13,9 @@ class SettingsInteractor {
double get cameraEvCalibration => _userPreferencesService.cameraEvCalibration;
void setCameraEvCalibration(double value) => _userPreferencesService.cameraEvCalibration = value;
double get lightSensorEvCalibration => _userPreferencesService.lightSensorEvCalibration;
void setLightSensorEvCalibration(double value) => _userPreferencesService.lightSensorEvCalibration = value;
bool get isHapticsEnabled => _userPreferencesService.haptics;
/// Executes vibration if haptics are enabled in settings

View file

@ -30,6 +30,7 @@
"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.",
"camera": "Camera",
"lightSensor": "Light sensor",
"general": "General",
"haptics": "Haptics",
"theme": "Theme",

View file

@ -6,7 +6,9 @@ import 'state_communication_metering.dart';
class MeteringCommunicationBloc
extends Bloc<MeteringCommunicationEvent, MeteringCommunicationState> {
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)));
}
}

View file

@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:lightmeter/data/models/ev_source_type.dart';
import 'package:lightmeter/res/dimens.dart';
import 'package:provider/provider.dart';
import 'components/widget_button_measure.dart';
import 'components/widget_button_secondary.dart';
@ -36,7 +38,9 @@ class MeteringBottomControls extends StatelessWidget {
Expanded(
child: MeteringSecondaryButton(
onPressed: onSwitchEvSourceType!,
icon: Icons.sync,
icon: context.watch<EvSourceType>() != EvSourceType.camera
? Icons.camera_rear
: Icons.wb_incandescent,
),
)
else

View file

@ -34,8 +34,8 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
double _currentExposureOffset = 0.0;
CameraContainerBloc(
MeteringCommunicationBloc communicationBloc,
this._meteringInteractor,
MeteringCommunicationBloc communicationBloc,
) : super(
communicationBloc,
const CameraInitState(),

View file

@ -33,8 +33,8 @@ class CameraContainerProvider extends StatelessWidget {
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => CameraContainerBloc(
context.read<MeteringCommunicationBloc>(),
context.read<MeteringInteractor>(),
context.read<MeteringCommunicationBloc>(),
),
child: CameraContainer(
fastest: fastest,

View file

@ -15,7 +15,6 @@ import 'components/camera_controls/widget_camera_controls.dart';
import 'event_container_camera.dart';
import 'state_container_camera.dart';
// TODO: add stepHeight calculation based on Text
class CameraContainer extends StatelessWidget {
final ExposurePair? fastest;
final ExposurePair? slowest;

View file

@ -18,8 +18,8 @@ class LightSensorContainerBloc
StreamSubscription<int>? _luxSubscriptions;
LightSensorContainerBloc(
MeteringCommunicationBloc communicationBloc,
this._meteringInteractor,
MeteringCommunicationBloc communicationBloc,
) : super(
communicationBloc,
const LightSensorInitState(),
@ -30,7 +30,9 @@ class LightSensorContainerBloc
if (communicationState is communication_states.MeasureState) {
if (_luxSubscriptions == null) {
_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 {
_luxSubscriptions?.cancel().then((_) => _luxSubscriptions = null);

View file

@ -32,9 +32,10 @@ class LightSensorContainerProvider extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
lazy: false,
create: (context) => LightSensorContainerBloc(
context.read<MeteringCommunicationBloc>(),
context.read<MeteringInteractor>(),
context.read<MeteringCommunicationBloc>(),
),
child: LightSensorContainer(
fastest: fastest,

View file

@ -1,4 +1,3 @@
import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';

View file

@ -8,26 +8,47 @@ class CalibrationDialogBloc extends Bloc<CalibrationDialogEvent, CalibrationDial
final SettingsInteractor _settingsInteractor;
late double _cameraEvCalibration = _settingsInteractor.cameraEvCalibration;
late double _lightSensorEvCalibration = _settingsInteractor.lightSensorEvCalibration;
CalibrationDialogBloc(this._settingsInteractor)
: super(CalibrationDialogState(_settingsInteractor.cameraEvCalibration)) {
: super(
CalibrationDialogState(
_settingsInteractor.cameraEvCalibration,
_settingsInteractor.lightSensorEvCalibration,
),
) {
on<CameraEvCalibrationChangedEvent>(_onCameraEvCalibrationChanged);
on<CameraEvCalibrationResetEvent>(_onCameraEvCalibrationReset);
on<LightSensorEvCalibrationChangedEvent>(_onLightSensorEvCalibrationChanged);
on<LightSensorEvCalibrationResetEvent>(_onLightSensorEvCalibrationReset);
on<SaveCalibrationDialogEvent>(_onSaveCalibration);
}
void _onCameraEvCalibrationChanged(CameraEvCalibrationChangedEvent event, Emitter emit) {
_cameraEvCalibration = event.value;
emit(CalibrationDialogState(event.value));
emit(CalibrationDialogState(_cameraEvCalibration, _lightSensorEvCalibration));
}
void _onCameraEvCalibrationReset(CameraEvCalibrationResetEvent event, Emitter emit) {
_settingsInteractor.quickVibration();
_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, __) {
_settingsInteractor.setCameraEvCalibration(_cameraEvCalibration);
_settingsInteractor.setLightSensorEvCalibration(_lightSensorEvCalibration);
}
}

View file

@ -12,6 +12,16 @@ class CameraEvCalibrationResetEvent extends CalibrationDialogEvent {
const CameraEvCalibrationResetEvent();
}
class LightSensorEvCalibrationChangedEvent extends CalibrationDialogEvent {
final double value;
const LightSensorEvCalibrationChangedEvent(this.value);
}
class LightSensorEvCalibrationResetEvent extends CalibrationDialogEvent {
const LightSensorEvCalibrationResetEvent();
}
class SaveCalibrationDialogEvent extends CalibrationDialogEvent {
const SaveCalibrationDialogEvent();
}

View file

@ -1,5 +1,9 @@
class CalibrationDialogState {
final double cameraEvCalibration;
final double lightSensorEvCalibration;
const CalibrationDialogState(this.cameraEvCalibration);
const CalibrationDialogState(
this.cameraEvCalibration,
this.lightSensorEvCalibration,
);
}

View file

@ -9,16 +9,9 @@ import 'package:lightmeter/utils/to_string_signed.dart';
import 'bloc_dialog_calibration.dart';
import 'state_dialog_calibration.dart';
class CalibrationDialog extends StatefulWidget {
class CalibrationDialog extends StatelessWidget {
const CalibrationDialog({super.key});
@override
State<CalibrationDialog> createState() => _CalibrationDialogState();
}
class _CalibrationDialogState extends State<CalibrationDialog> {
CalibrationDialogBloc get bloc => context.read<CalibrationDialogBloc>();
@override
Widget build(BuildContext context) {
return AlertDialog(
@ -30,17 +23,39 @@ class _CalibrationDialogState extends State<CalibrationDialog> {
),
title: Text(S.of(context).calibration),
contentPadding: const EdgeInsets.symmetric(horizontal: Dimens.paddingL),
content: BlocBuilder<CalibrationDialogBloc, CalibrationDialogState>(
builder: (context, state) => Column(
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(S.of(context).calibrationMessage),
const SizedBox(height: Dimens.grid16),
_CalibrationUnit(
title: S.of(context).camera,
value: state.cameraEvCalibration,
onChanged: (value) => bloc.add(CameraEvCalibrationChangedEvent(value)),
onReset: () => bloc.add(const CameraEvCalibrationResetEvent()),
BlocBuilder<CalibrationDialogBloc, CalibrationDialogState>(
buildWhen: (previous, current) =>
previous.cameraEvCalibration != current.cameraEvCalibration,
builder: (context, state) => _CalibrationUnit(
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(
onPressed: () {
bloc.add(const SaveCalibrationDialogEvent());
context.read<CalibrationDialogBloc>().add(const SaveCalibrationDialogEvent());
Navigator.of(context).pop();
},
child: Text(S.of(context).save),