mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2025-09-18 15:36:42 +00:00
add/edit pinhole profiles
This commit is contained in:
parent
3aa0014b6a
commit
76a6754a3b
12 changed files with 338 additions and 254 deletions
|
@ -34,6 +34,8 @@
|
||||||
"calibrationMessage": "Die Messgenauigkeit hängt von der Gerätehardware ab. Testen Sie die App und kalibrieren Sie EV-Werte für beste Ergebnisse",
|
"calibrationMessage": "Die Messgenauigkeit hängt von der Gerätehardware ab. Testen Sie die App und kalibrieren Sie EV-Werte für beste Ergebnisse",
|
||||||
"calibrationMessageCameraOnly": "Die Messgenauigkeit hängt von der Kamera ab. Testen Sie die App und kalibrieren Sie EV-Werte für beste Ergebnisse",
|
"calibrationMessageCameraOnly": "Die Messgenauigkeit hängt von der Kamera ab. Testen Sie die App und kalibrieren Sie EV-Werte für beste Ergebnisse",
|
||||||
"camera": "Kamera",
|
"camera": "Kamera",
|
||||||
|
"pinholeCamera": "Lochkamera",
|
||||||
|
"equipmentProfileType": "Ausrüstungsprofiltyp",
|
||||||
"lightSensor": "Lichtsensor",
|
"lightSensor": "Lichtsensor",
|
||||||
"showEv100": "EV\u2081\u2080\u2080 anzeigen",
|
"showEv100": "EV\u2081\u2080\u2080 anzeigen",
|
||||||
"meteringScreenLayout": "Messansicht Layout",
|
"meteringScreenLayout": "Messansicht Layout",
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
"calibrationMessage": "Measurement accuracy depends on your device's hardware. Test the app and calibrate EV values for optimal results",
|
"calibrationMessage": "Measurement accuracy depends on your device's hardware. Test the app and calibrate EV values for optimal results",
|
||||||
"calibrationMessageCameraOnly": "Measurement accuracy depends on your device's camera. Test the app and calibrate EV values for optimal results",
|
"calibrationMessageCameraOnly": "Measurement accuracy depends on your device's camera. Test the app and calibrate EV values for optimal results",
|
||||||
"camera": "Camera",
|
"camera": "Camera",
|
||||||
|
"pinholeCamera": "Pinhole Camera",
|
||||||
|
"equipmentProfileType": "Equipment profile type",
|
||||||
"lightSensor": "Light sensor",
|
"lightSensor": "Light sensor",
|
||||||
"showEv100": "Show EV\u2081\u2080\u2080",
|
"showEv100": "Show EV\u2081\u2080\u2080",
|
||||||
"meteringScreenLayout": "Metering screen layout",
|
"meteringScreenLayout": "Metering screen layout",
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
"calibrationMessage": "La précision dépend du matériel de l'appareil. Testez l'app et calibrez les valeurs EV pour de meilleurs résultats",
|
"calibrationMessage": "La précision dépend du matériel de l'appareil. Testez l'app et calibrez les valeurs EV pour de meilleurs résultats",
|
||||||
"calibrationMessageCameraOnly": "La précision dépend de la caméra de l'appareil. Testez l'app et calibrez les valeurs EV pour de meilleurs résultats",
|
"calibrationMessageCameraOnly": "La précision dépend de la caméra de l'appareil. Testez l'app et calibrez les valeurs EV pour de meilleurs résultats",
|
||||||
"camera": "Caméra",
|
"camera": "Caméra",
|
||||||
|
"pinholeCamera": "Sténopé",
|
||||||
|
"equipmentProfileType": "Type de profil d'équipement",
|
||||||
"lightSensor": "Capteur de lumière",
|
"lightSensor": "Capteur de lumière",
|
||||||
"showEv100": "Montrer EV\u2081\u2080\u2080",
|
"showEv100": "Montrer EV\u2081\u2080\u2080",
|
||||||
"meteringScreenLayout": "Disposition de l'écran de mesure",
|
"meteringScreenLayout": "Disposition de l'écran de mesure",
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
"calibrationMessage": "Dokładność pomiaru zależy od sprzętu urządzenia. Przetestuj aplikację i skalibruj wartości EV dla optymalnych wyników",
|
"calibrationMessage": "Dokładność pomiaru zależy od sprzętu urządzenia. Przetestuj aplikację i skalibruj wartości EV dla optymalnych wyników",
|
||||||
"calibrationMessageCameraOnly": "Dokładność pomiaru zależy od kamery urządzenia. Przetestuj aplikację i skalibruj wartości EV dla optymalnych wyników",
|
"calibrationMessageCameraOnly": "Dokładność pomiaru zależy od kamery urządzenia. Przetestuj aplikację i skalibruj wartości EV dla optymalnych wyników",
|
||||||
"camera": "Kamera",
|
"camera": "Kamera",
|
||||||
|
"pinholeCamera": "Kamera otworkowa",
|
||||||
|
"equipmentProfileType": "Typ profilu sprzętu",
|
||||||
"lightSensor": "Czujnik światła",
|
"lightSensor": "Czujnik światła",
|
||||||
"showEv100": "Pokaż EV\u2081\u2080\u2080",
|
"showEv100": "Pokaż EV\u2081\u2080\u2080",
|
||||||
"meteringScreenLayout": "Układ ekranu pomiaru",
|
"meteringScreenLayout": "Układ ekranu pomiaru",
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
"calibrationMessage": "Точность измерений данного приложения полностью зависит от точности камеры и датчика освещенности вашего устройства. Поэтому рекомендуется самостоятельно подобрать калибровочные значения, которые дадут желаемый результат измерений.",
|
"calibrationMessage": "Точность измерений данного приложения полностью зависит от точности камеры и датчика освещенности вашего устройства. Поэтому рекомендуется самостоятельно подобрать калибровочные значения, которые дадут желаемый результат измерений.",
|
||||||
"calibrationMessageCameraOnly": "Точность измерений данного приложения полностью зависит от точности камеры вашего устройства. Поэтому рекомендуется самостоятельно подобрать калибровочное значение, которое даст желаемый результат измерений.",
|
"calibrationMessageCameraOnly": "Точность измерений данного приложения полностью зависит от точности камеры вашего устройства. Поэтому рекомендуется самостоятельно подобрать калибровочное значение, которое даст желаемый результат измерений.",
|
||||||
"camera": "Камера",
|
"camera": "Камера",
|
||||||
|
"pinholeCamera": "Пинхол-камера",
|
||||||
|
"equipmentProfileType": "Тип профиля оборудования",
|
||||||
"lightSensor": "Датчик освещённости",
|
"lightSensor": "Датчик освещённости",
|
||||||
"showEv100": "Показывать EV\u2081\u2080\u2080",
|
"showEv100": "Показывать EV\u2081\u2080\u2080",
|
||||||
"meteringScreenLayout": "Элементы главного экрана",
|
"meteringScreenLayout": "Элементы главного экрана",
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
"calibrationMessage": "测量精度取决于设备硬件。请测试并校准 EV 值以获得最佳结果。",
|
"calibrationMessage": "测量精度取决于设备硬件。请测试并校准 EV 值以获得最佳结果。",
|
||||||
"calibrationMessageCameraOnly": "测量精度取决于设备摄像头。请测试并校准 EV 值以获得最佳结果。",
|
"calibrationMessageCameraOnly": "测量精度取决于设备摄像头。请测试并校准 EV 值以获得最佳结果。",
|
||||||
"camera": "相机",
|
"camera": "相机",
|
||||||
|
"pinholeCamera": "针孔相机",
|
||||||
|
"equipmentProfileType": "设备配置类型",
|
||||||
"lightSensor": "光线传感器",
|
"lightSensor": "光线传感器",
|
||||||
"showEv100": "显示 EV\u2081\u2080\u2080",
|
"showEv100": "显示 EV\u2081\u2080\u2080",
|
||||||
"meteringScreenLayout": "布局",
|
"meteringScreenLayout": "布局",
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:lightmeter/providers/equipment_profile_provider.dart';
|
import 'package:lightmeter/providers/equipment_profile_provider.dart';
|
||||||
import 'package:lightmeter/screens/equipment_profile_edit/event_equipment_profile_edit.dart';
|
import 'package:lightmeter/screens/equipment_profile_edit/event_equipment_profile_edit.dart';
|
||||||
|
@ -5,189 +6,199 @@ import 'package:lightmeter/screens/equipment_profile_edit/state_equipment_profil
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
class EquipmentProfileEditBloc extends Bloc<EquipmentProfileEditEvent, EquipmentProfileEditState> {
|
sealed class IEquipmentProfileEditBloc<T extends IEquipmentProfile>
|
||||||
|
extends Bloc<IEquipmentProfileEditEvent<T>, EquipmentProfileEditState<T>> {
|
||||||
|
@protected
|
||||||
final EquipmentProfilesProviderState profilesProvider;
|
final EquipmentProfilesProviderState profilesProvider;
|
||||||
final EquipmentProfile _originalEquipmentProfile;
|
@protected
|
||||||
EquipmentProfile _newEquipmentProfile;
|
final T originalEquipmentProfile;
|
||||||
final bool _isEdit;
|
@protected
|
||||||
|
final bool isEdit;
|
||||||
|
|
||||||
factory EquipmentProfileEditBloc(
|
IEquipmentProfileEditBloc(
|
||||||
EquipmentProfilesProviderState profilesProvider, {
|
this.profilesProvider, {
|
||||||
required EquipmentProfile? profile,
|
required T profile,
|
||||||
required bool isEdit,
|
required this.isEdit,
|
||||||
}) =>
|
}) : originalEquipmentProfile = profile,
|
||||||
profile != null
|
|
||||||
? EquipmentProfileEditBloc._(
|
|
||||||
profilesProvider,
|
|
||||||
profile,
|
|
||||||
isEdit,
|
|
||||||
)
|
|
||||||
: EquipmentProfileEditBloc._(
|
|
||||||
profilesProvider,
|
|
||||||
EquipmentProfilesProvider.defaultProfile,
|
|
||||||
isEdit,
|
|
||||||
);
|
|
||||||
|
|
||||||
EquipmentProfileEditBloc._(
|
|
||||||
this.profilesProvider,
|
|
||||||
EquipmentProfile profile,
|
|
||||||
this._isEdit,
|
|
||||||
) : _originalEquipmentProfile = profile,
|
|
||||||
_newEquipmentProfile = profile,
|
|
||||||
super(
|
super(
|
||||||
EquipmentProfileEditState(
|
EquipmentProfileEditState<T>(
|
||||||
name: profile.name,
|
profile: profile,
|
||||||
apertureValues: profile.apertureValues,
|
|
||||||
shutterSpeedValues: profile.shutterSpeedValues,
|
|
||||||
isoValues: profile.isoValues,
|
|
||||||
ndValues: profile.ndValues,
|
|
||||||
lensZoom: profile.lensZoom,
|
|
||||||
exposureOffset: profile.exposureOffset,
|
|
||||||
canSave: false,
|
canSave: false,
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
on<EquipmentProfileEditEvent>(
|
on<IEquipmentProfileEditEvent<T>>(mapEventToState);
|
||||||
(event, emit) async {
|
}
|
||||||
switch (event) {
|
|
||||||
case final EquipmentProfileNameChangedEvent e:
|
@protected
|
||||||
await _onNameChanged(e, emit);
|
@mustCallSuper
|
||||||
case final EquipmentProfileApertureValuesChangedEvent e:
|
Future<void> mapEventToState(IEquipmentProfileEditEvent<T> event, Emitter emit) async {
|
||||||
await _onApertureValuesChanged(e, emit);
|
switch (event) {
|
||||||
case final EquipmentProfileShutterSpeedValuesChangedEvent e:
|
case EquipmentProfileSaveEvent():
|
||||||
await _onShutterSpeedValuesChanged(e, emit);
|
await _onSave(event, emit);
|
||||||
case final EquipmentProfileIsoValuesChangedEvent e:
|
case EquipmentProfileCopyEvent():
|
||||||
await _onIsoValuesChanged(e, emit);
|
await _onCopy(event, emit);
|
||||||
case final EquipmentProfileNdValuesChangedEvent e:
|
case EquipmentProfileDeleteEvent():
|
||||||
await _onNdValuesChanged(e, emit);
|
await _onDelete(event, emit);
|
||||||
case final EquipmentProfileLensZoomChangedEvent e:
|
default:
|
||||||
await _onLensZoomChanged(e, emit);
|
}
|
||||||
case final EquipmentProfileExposureOffsetChangedEvent e:
|
}
|
||||||
await _onExposureOffsetChanged(e, emit);
|
|
||||||
case EquipmentProfileSaveEvent():
|
@protected
|
||||||
await _onSave(event, emit);
|
Future<T> createProfile(String id);
|
||||||
case EquipmentProfileCopyEvent():
|
|
||||||
await _onCopy(event, emit);
|
@protected
|
||||||
case EquipmentProfileDeleteEvent():
|
void emitProfile(T profile, Emitter emit) {
|
||||||
await _onDelete(event, emit);
|
emit(
|
||||||
}
|
state.copyWith(
|
||||||
},
|
profile: profile,
|
||||||
|
canSave: _canSave(profile),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onSave(EquipmentProfileSaveEvent<T> _, Emitter emit) async {
|
||||||
|
emit(state.copyWith(isLoading: true));
|
||||||
|
final profileId = isEdit ? originalEquipmentProfile.id : const Uuid().v1();
|
||||||
|
final newProfile = await createProfile(profileId);
|
||||||
|
assert(newProfile.id == profileId, 'The new profile id must be the same as the original profile id');
|
||||||
|
await profilesProvider.addProfile(newProfile);
|
||||||
|
emit(state.copyWith(isLoading: false));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onCopy(EquipmentProfileCopyEvent<T> _, Emitter emit) async {
|
||||||
|
emit(state.copyWith(isLoading: true));
|
||||||
|
emit(state.copyWith(isLoading: false, profileToCopy: state.profile));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onDelete(EquipmentProfileDeleteEvent<T> _, Emitter emit) async {
|
||||||
|
emit(state.copyWith(isLoading: true));
|
||||||
|
await profilesProvider.deleteProfile(originalEquipmentProfile);
|
||||||
|
emit(state.copyWith(isLoading: false));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _canSave(T profile) => profile != originalEquipmentProfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
class EquipmentProfileEditBloc extends IEquipmentProfileEditBloc<EquipmentProfile> {
|
||||||
|
EquipmentProfileEditBloc(
|
||||||
|
super.profilesProvider, {
|
||||||
|
required super.profile,
|
||||||
|
required super.isEdit,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> mapEventToState(IEquipmentProfileEditEvent<EquipmentProfile> event, Emitter emit) async {
|
||||||
|
switch (event) {
|
||||||
|
case final EquipmentProfileNameChangedEvent e:
|
||||||
|
await _onNameChanged(e, emit);
|
||||||
|
case final EquipmentProfileApertureValuesChangedEvent e:
|
||||||
|
await _onApertureValuesChanged(e, emit);
|
||||||
|
case final EquipmentProfileShutterSpeedValuesChangedEvent e:
|
||||||
|
await _onShutterSpeedValuesChanged(e, emit);
|
||||||
|
case final EquipmentProfileIsoValuesChangedEvent e:
|
||||||
|
await _onIsoValuesChanged(e, emit);
|
||||||
|
case final EquipmentProfileNdValuesChangedEvent e:
|
||||||
|
await _onNdValuesChanged(e, emit);
|
||||||
|
case final EquipmentProfileLensZoomChangedEvent e:
|
||||||
|
await _onLensZoomChanged(e, emit);
|
||||||
|
case final EquipmentProfileExposureOffsetChangedEvent e:
|
||||||
|
await _onExposureOffsetChanged(e, emit);
|
||||||
|
default:
|
||||||
|
return super.mapEventToState(event, emit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<EquipmentProfile> createProfile(String id) async {
|
||||||
|
return EquipmentProfile(
|
||||||
|
id: id,
|
||||||
|
name: state.profile.name,
|
||||||
|
apertureValues: state.profile.apertureValues,
|
||||||
|
shutterSpeedValues: state.profile.shutterSpeedValues,
|
||||||
|
isoValues: state.profile.isoValues,
|
||||||
|
ndValues: state.profile.ndValues,
|
||||||
|
lensZoom: state.profile.lensZoom,
|
||||||
|
exposureOffset: state.profile.exposureOffset,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onNameChanged(EquipmentProfileNameChangedEvent event, Emitter emit) async {
|
Future<void> _onNameChanged(EquipmentProfileNameChangedEvent event, Emitter emit) async {
|
||||||
_newEquipmentProfile = _newEquipmentProfile.copyWith(name: event.name);
|
emitProfile(state.profile.copyWith(name: event.name), emit);
|
||||||
emit(
|
|
||||||
state.copyWith(
|
|
||||||
name: event.name,
|
|
||||||
canSave: _canSave(event.name, state.lensZoom),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onApertureValuesChanged(EquipmentProfileApertureValuesChangedEvent event, Emitter emit) async {
|
Future<void> _onApertureValuesChanged(EquipmentProfileApertureValuesChangedEvent event, Emitter emit) async {
|
||||||
_newEquipmentProfile = _newEquipmentProfile.copyWith(apertureValues: event.apertureValues);
|
emitProfile(state.profile.copyWith(apertureValues: event.apertureValues), emit);
|
||||||
emit(
|
|
||||||
state.copyWith(
|
|
||||||
apertureValues: event.apertureValues,
|
|
||||||
canSave: _canSave(state.name, state.lensZoom),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onShutterSpeedValuesChanged(EquipmentProfileShutterSpeedValuesChangedEvent event, Emitter emit) async {
|
Future<void> _onShutterSpeedValuesChanged(EquipmentProfileShutterSpeedValuesChangedEvent event, Emitter emit) async {
|
||||||
_newEquipmentProfile = _newEquipmentProfile.copyWith(shutterSpeedValues: event.shutterSpeedValues);
|
emitProfile(state.profile.copyWith(shutterSpeedValues: event.shutterSpeedValues), emit);
|
||||||
emit(
|
|
||||||
state.copyWith(
|
|
||||||
shutterSpeedValues: event.shutterSpeedValues,
|
|
||||||
canSave: _canSave(state.name, state.lensZoom),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onIsoValuesChanged(EquipmentProfileIsoValuesChangedEvent event, Emitter emit) async {
|
Future<void> _onIsoValuesChanged(EquipmentProfileIsoValuesChangedEvent event, Emitter emit) async {
|
||||||
_newEquipmentProfile = _newEquipmentProfile.copyWith(isoValues: event.isoValues);
|
emitProfile(state.profile.copyWith(isoValues: event.isoValues), emit);
|
||||||
emit(
|
|
||||||
state.copyWith(
|
|
||||||
isoValues: event.isoValues,
|
|
||||||
canSave: _canSave(state.name, state.lensZoom),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onNdValuesChanged(EquipmentProfileNdValuesChangedEvent event, Emitter emit) async {
|
Future<void> _onNdValuesChanged(EquipmentProfileNdValuesChangedEvent event, Emitter emit) async {
|
||||||
_newEquipmentProfile = _newEquipmentProfile.copyWith(ndValues: event.ndValues);
|
emitProfile(state.profile.copyWith(ndValues: event.ndValues), emit);
|
||||||
emit(
|
|
||||||
state.copyWith(
|
|
||||||
ndValues: event.ndValues,
|
|
||||||
canSave: _canSave(state.name, state.lensZoom),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onLensZoomChanged(EquipmentProfileLensZoomChangedEvent event, Emitter emit) async {
|
Future<void> _onLensZoomChanged(EquipmentProfileLensZoomChangedEvent event, Emitter emit) async {
|
||||||
_newEquipmentProfile = _newEquipmentProfile.copyWith(lensZoom: event.lensZoom);
|
emitProfile(state.profile.copyWith(lensZoom: event.lensZoom), emit);
|
||||||
emit(
|
|
||||||
state.copyWith(
|
|
||||||
lensZoom: event.lensZoom,
|
|
||||||
canSave: _canSave(state.name, event.lensZoom),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onExposureOffsetChanged(EquipmentProfileExposureOffsetChangedEvent event, Emitter emit) async {
|
Future<void> _onExposureOffsetChanged(EquipmentProfileExposureOffsetChangedEvent event, Emitter emit) async {
|
||||||
_newEquipmentProfile = _newEquipmentProfile.copyWith(exposureOffset: event.exposureOffset);
|
emitProfile(state.profile.copyWith(exposureOffset: event.exposureOffset), emit);
|
||||||
emit(
|
}
|
||||||
state.copyWith(
|
}
|
||||||
exposureOffset: event.exposureOffset,
|
|
||||||
canSave: _canSave(state.name, event.exposureOffset),
|
class PinholeEquipmentProfileEditBloc extends IEquipmentProfileEditBloc<PinholeEquipmentProfile> {
|
||||||
),
|
PinholeEquipmentProfileEditBloc(
|
||||||
|
super.profilesProvider, {
|
||||||
|
required super.profile,
|
||||||
|
required super.isEdit,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> mapEventToState(IEquipmentProfileEditEvent<PinholeEquipmentProfile> event, Emitter emit) async {
|
||||||
|
switch (event) {
|
||||||
|
case final EquipmentProfileNameChangedEvent e:
|
||||||
|
await _onNameChanged(e, emit);
|
||||||
|
case final EquipmentProfileApertureValuesChangedEvent e:
|
||||||
|
await _onApertureValuesChanged(e, emit);
|
||||||
|
case final EquipmentProfileLensZoomChangedEvent e:
|
||||||
|
await _onLensZoomChanged(e, emit);
|
||||||
|
case final EquipmentProfileExposureOffsetChangedEvent e:
|
||||||
|
await _onExposureOffsetChanged(e, emit);
|
||||||
|
default:
|
||||||
|
return super.mapEventToState(event, emit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<PinholeEquipmentProfile> createProfile(String id) async {
|
||||||
|
return PinholeEquipmentProfile(
|
||||||
|
id: id,
|
||||||
|
name: state.profile.name,
|
||||||
|
aperture: state.profile.aperture,
|
||||||
|
isoValues: state.profile.isoValues,
|
||||||
|
lensZoom: state.profile.lensZoom,
|
||||||
|
exposureOffset: state.profile.exposureOffset,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onSave(EquipmentProfileSaveEvent _, Emitter emit) async {
|
Future<void> _onNameChanged(EquipmentProfileNameChangedEvent event, Emitter emit) async {
|
||||||
emit(state.copyWith(isLoading: true));
|
emitProfile(state.profile.copyWith(name: event.name), emit);
|
||||||
if (_isEdit) {
|
|
||||||
await profilesProvider.updateProfile(
|
|
||||||
EquipmentProfile(
|
|
||||||
id: _originalEquipmentProfile.id,
|
|
||||||
name: state.name,
|
|
||||||
apertureValues: state.apertureValues,
|
|
||||||
ndValues: state.ndValues,
|
|
||||||
shutterSpeedValues: state.shutterSpeedValues,
|
|
||||||
isoValues: state.isoValues,
|
|
||||||
lensZoom: state.lensZoom,
|
|
||||||
exposureOffset: state.exposureOffset,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
await profilesProvider.addProfile(
|
|
||||||
EquipmentProfile(
|
|
||||||
id: const Uuid().v1(),
|
|
||||||
name: state.name,
|
|
||||||
apertureValues: state.apertureValues,
|
|
||||||
ndValues: state.ndValues,
|
|
||||||
shutterSpeedValues: state.shutterSpeedValues,
|
|
||||||
isoValues: state.isoValues,
|
|
||||||
lensZoom: state.lensZoom,
|
|
||||||
exposureOffset: state.exposureOffset,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
emit(state.copyWith(isLoading: false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onCopy(EquipmentProfileCopyEvent _, Emitter emit) async {
|
Future<void> _onApertureValuesChanged(EquipmentProfileApertureValuesChangedEvent event, Emitter emit) async {
|
||||||
emit(state.copyWith(isLoading: true));
|
//emitProfile(state.profile.copyWith(apertureValues: event.apertureValues), emit);
|
||||||
emit(state.copyWith(isLoading: false, profileToCopy: _originalEquipmentProfile));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onDelete(EquipmentProfileDeleteEvent _, Emitter emit) async {
|
Future<void> _onLensZoomChanged(EquipmentProfileLensZoomChangedEvent event, Emitter emit) async {
|
||||||
emit(state.copyWith(isLoading: true));
|
emitProfile(state.profile.copyWith(lensZoom: event.lensZoom), emit);
|
||||||
await profilesProvider.deleteProfile(_newEquipmentProfile);
|
|
||||||
emit(state.copyWith(isLoading: false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _canSave(String name, double? lensZoom) {
|
Future<void> _onExposureOffsetChanged(EquipmentProfileExposureOffsetChangedEvent event, Emitter emit) async {
|
||||||
return name.isNotEmpty && _newEquipmentProfile != _originalEquipmentProfile;
|
emitProfile(state.profile.copyWith(exposureOffset: event.exposureOffset), emit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,59 +1,59 @@
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
sealed class EquipmentProfileEditEvent {
|
sealed class IEquipmentProfileEditEvent<T extends IEquipmentProfile> {
|
||||||
const EquipmentProfileEditEvent();
|
const IEquipmentProfileEditEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
class EquipmentProfileNameChangedEvent extends EquipmentProfileEditEvent {
|
class EquipmentProfileNameChangedEvent<T extends IEquipmentProfile> extends IEquipmentProfileEditEvent<T> {
|
||||||
final String name;
|
final String name;
|
||||||
|
|
||||||
const EquipmentProfileNameChangedEvent(this.name);
|
const EquipmentProfileNameChangedEvent(this.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
class EquipmentProfileIsoValuesChangedEvent extends EquipmentProfileEditEvent {
|
class EquipmentProfileIsoValuesChangedEvent<T extends IEquipmentProfile> extends IEquipmentProfileEditEvent<T> {
|
||||||
final List<IsoValue> isoValues;
|
final List<IsoValue> isoValues;
|
||||||
|
|
||||||
const EquipmentProfileIsoValuesChangedEvent(this.isoValues);
|
const EquipmentProfileIsoValuesChangedEvent(this.isoValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
class EquipmentProfileNdValuesChangedEvent extends EquipmentProfileEditEvent {
|
class EquipmentProfileNdValuesChangedEvent extends IEquipmentProfileEditEvent<EquipmentProfile> {
|
||||||
final List<NdValue> ndValues;
|
final List<NdValue> ndValues;
|
||||||
|
|
||||||
const EquipmentProfileNdValuesChangedEvent(this.ndValues);
|
const EquipmentProfileNdValuesChangedEvent(this.ndValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
class EquipmentProfileApertureValuesChangedEvent extends EquipmentProfileEditEvent {
|
class EquipmentProfileApertureValuesChangedEvent extends IEquipmentProfileEditEvent<EquipmentProfile> {
|
||||||
final List<ApertureValue> apertureValues;
|
final List<ApertureValue> apertureValues;
|
||||||
|
|
||||||
const EquipmentProfileApertureValuesChangedEvent(this.apertureValues);
|
const EquipmentProfileApertureValuesChangedEvent(this.apertureValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
class EquipmentProfileShutterSpeedValuesChangedEvent extends EquipmentProfileEditEvent {
|
class EquipmentProfileShutterSpeedValuesChangedEvent extends IEquipmentProfileEditEvent<EquipmentProfile> {
|
||||||
final List<ShutterSpeedValue> shutterSpeedValues;
|
final List<ShutterSpeedValue> shutterSpeedValues;
|
||||||
|
|
||||||
const EquipmentProfileShutterSpeedValuesChangedEvent(this.shutterSpeedValues);
|
const EquipmentProfileShutterSpeedValuesChangedEvent(this.shutterSpeedValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
class EquipmentProfileLensZoomChangedEvent extends EquipmentProfileEditEvent {
|
class EquipmentProfileLensZoomChangedEvent<T extends IEquipmentProfile> extends IEquipmentProfileEditEvent<T> {
|
||||||
final double lensZoom;
|
final double lensZoom;
|
||||||
|
|
||||||
const EquipmentProfileLensZoomChangedEvent(this.lensZoom);
|
const EquipmentProfileLensZoomChangedEvent(this.lensZoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
class EquipmentProfileExposureOffsetChangedEvent extends EquipmentProfileEditEvent {
|
class EquipmentProfileExposureOffsetChangedEvent<T extends IEquipmentProfile> extends IEquipmentProfileEditEvent<T> {
|
||||||
final double exposureOffset;
|
final double exposureOffset;
|
||||||
|
|
||||||
const EquipmentProfileExposureOffsetChangedEvent(this.exposureOffset);
|
const EquipmentProfileExposureOffsetChangedEvent(this.exposureOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
class EquipmentProfileSaveEvent extends EquipmentProfileEditEvent {
|
class EquipmentProfileSaveEvent<T extends IEquipmentProfile> extends IEquipmentProfileEditEvent<T> {
|
||||||
const EquipmentProfileSaveEvent();
|
const EquipmentProfileSaveEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
class EquipmentProfileCopyEvent extends EquipmentProfileEditEvent {
|
class EquipmentProfileCopyEvent<T extends IEquipmentProfile> extends IEquipmentProfileEditEvent<T> {
|
||||||
const EquipmentProfileCopyEvent();
|
const EquipmentProfileCopyEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
class EquipmentProfileDeleteEvent extends EquipmentProfileEditEvent {
|
class EquipmentProfileDeleteEvent<T extends IEquipmentProfile> extends IEquipmentProfileEditEvent<T> {
|
||||||
const EquipmentProfileDeleteEvent();
|
const EquipmentProfileDeleteEvent();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,14 @@ import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
enum EquipmentProfileEditType { add, edit }
|
enum EquipmentProfileEditType { add, edit }
|
||||||
|
|
||||||
class EquipmentProfileEditArgs {
|
class EquipmentProfileEditArgs<T extends IEquipmentProfile> {
|
||||||
final EquipmentProfileEditType editType;
|
final EquipmentProfileEditType editType;
|
||||||
final EquipmentProfile? profile;
|
final T profile;
|
||||||
|
|
||||||
const EquipmentProfileEditArgs({required this.editType, this.profile});
|
const EquipmentProfileEditArgs({
|
||||||
|
required this.editType,
|
||||||
|
required this.profile,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class EquipmentProfileEditFlow extends StatelessWidget {
|
class EquipmentProfileEditFlow extends StatelessWidget {
|
||||||
|
@ -25,13 +28,50 @@ class EquipmentProfileEditFlow extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
switch (args.profile) {
|
||||||
create: (_) => EquipmentProfileEditBloc(
|
case final EquipmentProfile profile:
|
||||||
EquipmentProfilesProvider.of(context),
|
return _IEquipmentProfileBlocProvider<EquipmentProfile, EquipmentProfileEditBloc>(
|
||||||
profile: args.profile,
|
create: (_) => EquipmentProfileEditBloc(
|
||||||
isEdit: _isEdit,
|
EquipmentProfilesProvider.of(context),
|
||||||
|
profile: profile,
|
||||||
|
isEdit: _isEdit,
|
||||||
|
),
|
||||||
|
isEdit: _isEdit,
|
||||||
|
);
|
||||||
|
case final PinholeEquipmentProfile profile:
|
||||||
|
return _IEquipmentProfileBlocProvider<PinholeEquipmentProfile, PinholeEquipmentProfileEditBloc>(
|
||||||
|
create: (_) => PinholeEquipmentProfileEditBloc(
|
||||||
|
EquipmentProfilesProvider.of(context),
|
||||||
|
profile: profile,
|
||||||
|
isEdit: _isEdit,
|
||||||
|
),
|
||||||
|
isEdit: _isEdit,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _IEquipmentProfileBlocProvider<T extends IEquipmentProfile, V extends IEquipmentProfileEditBloc<T>>
|
||||||
|
extends StatelessWidget {
|
||||||
|
final V Function(BuildContext context) create;
|
||||||
|
final bool isEdit;
|
||||||
|
|
||||||
|
const _IEquipmentProfileBlocProvider({
|
||||||
|
required this.create,
|
||||||
|
required this.isEdit,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider<IEquipmentProfileEditBloc<T>>(
|
||||||
|
create: create,
|
||||||
|
child: Builder(
|
||||||
|
builder: (context) => BlocProvider<V>.value(
|
||||||
|
value: context.read<IEquipmentProfileEditBloc<T>>() as V,
|
||||||
|
child: EquipmentProfileEditScreen<T>(isEdit: isEdit),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: EquipmentProfileEditScreen(isEdit: _isEdit),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ import 'package:lightmeter/utils/double_to_zoom.dart';
|
||||||
import 'package:lightmeter/utils/to_string_signed.dart';
|
import 'package:lightmeter/utils/to_string_signed.dart';
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
class EquipmentProfileEditScreen extends StatefulWidget {
|
class EquipmentProfileEditScreen<T extends IEquipmentProfile> extends StatefulWidget {
|
||||||
final bool isEdit;
|
final bool isEdit;
|
||||||
|
|
||||||
const EquipmentProfileEditScreen({
|
const EquipmentProfileEditScreen({
|
||||||
|
@ -26,13 +26,13 @@ class EquipmentProfileEditScreen extends StatefulWidget {
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<EquipmentProfileEditScreen> createState() => _EquipmentProfileEditScreenState();
|
State<EquipmentProfileEditScreen<T>> createState() => _EquipmentProfileEditScreenState<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _EquipmentProfileEditScreenState extends State<EquipmentProfileEditScreen> {
|
class _EquipmentProfileEditScreenState<T extends IEquipmentProfile> extends State<EquipmentProfileEditScreen<T>> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocConsumer<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
return BlocConsumer<IEquipmentProfileEditBloc<T>, EquipmentProfileEditState<T>>(
|
||||||
listenWhen: (previous, current) => previous.isLoading != current.isLoading,
|
listenWhen: (previous, current) => previous.isLoading != current.isLoading,
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
if (state.isLoading) {
|
if (state.isLoading) {
|
||||||
|
@ -41,9 +41,9 @@ class _EquipmentProfileEditScreenState extends State<EquipmentProfileEditScreen>
|
||||||
if (state.profileToCopy != null) {
|
if (state.profileToCopy != null) {
|
||||||
Navigator.of(context).pushReplacementNamed(
|
Navigator.of(context).pushReplacementNamed(
|
||||||
NavigationRoutes.equipmentProfileEditScreen.name,
|
NavigationRoutes.equipmentProfileEditScreen.name,
|
||||||
arguments: EquipmentProfileEditArgs(
|
arguments: EquipmentProfileEditArgs<T>(
|
||||||
editType: EquipmentProfileEditType.add,
|
editType: EquipmentProfileEditType.add,
|
||||||
profile: state.profileToCopy,
|
profile: state.profileToCopy!,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -57,25 +57,25 @@ class _EquipmentProfileEditScreenState extends State<EquipmentProfileEditScreen>
|
||||||
child: SliverScreen(
|
child: SliverScreen(
|
||||||
title: Text(widget.isEdit ? S.of(context).editEquipmentProfileTitle : S.of(context).addEquipmentProfileTitle),
|
title: Text(widget.isEdit ? S.of(context).editEquipmentProfileTitle : S.of(context).addEquipmentProfileTitle),
|
||||||
appBarActions: [
|
appBarActions: [
|
||||||
BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
BlocBuilder<IEquipmentProfileEditBloc<T>, EquipmentProfileEditState<T>>(
|
||||||
buildWhen: (previous, current) => previous.canSave != current.canSave,
|
buildWhen: (previous, current) => previous.canSave != current.canSave,
|
||||||
builder: (context, state) => IconButton(
|
builder: (context, state) => IconButton(
|
||||||
onPressed: state.canSave
|
onPressed: state.canSave
|
||||||
? () {
|
? () {
|
||||||
context.read<EquipmentProfileEditBloc>().add(const EquipmentProfileSaveEvent());
|
context.read<IEquipmentProfileEditBloc<T>>().add(const EquipmentProfileSaveEvent());
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
icon: const Icon(Icons.save_outlined),
|
icon: const Icon(Icons.save_outlined),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (widget.isEdit)
|
if (widget.isEdit)
|
||||||
BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
BlocBuilder<IEquipmentProfileEditBloc<T>, EquipmentProfileEditState<T>>(
|
||||||
buildWhen: (previous, current) => previous.canSave != current.canSave,
|
buildWhen: (previous, current) => previous.canSave != current.canSave,
|
||||||
builder: (context, state) => IconButton(
|
builder: (context, state) => IconButton(
|
||||||
onPressed: state.canSave
|
onPressed: state.canSave
|
||||||
? null
|
? null
|
||||||
: () {
|
: () {
|
||||||
context.read<EquipmentProfileEditBloc>().add(const EquipmentProfileCopyEvent());
|
context.read<IEquipmentProfileEditBloc<T>>().add(const EquipmentProfileCopyEvent());
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.copy_outlined),
|
icon: const Icon(Icons.copy_outlined),
|
||||||
),
|
),
|
||||||
|
@ -83,7 +83,7 @@ class _EquipmentProfileEditScreenState extends State<EquipmentProfileEditScreen>
|
||||||
if (widget.isEdit)
|
if (widget.isEdit)
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.read<EquipmentProfileEditBloc>().add(const EquipmentProfileDeleteEvent());
|
context.read<IEquipmentProfileEditBloc<T>>().add(const EquipmentProfileDeleteEvent());
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.delete_outlined),
|
icon: const Icon(Icons.delete_outlined),
|
||||||
),
|
),
|
||||||
|
@ -102,16 +102,25 @@ class _EquipmentProfileEditScreenState extends State<EquipmentProfileEditScreen>
|
||||||
padding: const EdgeInsets.symmetric(vertical: Dimens.paddingM),
|
padding: const EdgeInsets.symmetric(vertical: Dimens.paddingM),
|
||||||
child: Opacity(
|
child: Opacity(
|
||||||
opacity: state.isLoading ? Dimens.disabledOpacity : Dimens.enabledOpacity,
|
opacity: state.isLoading ? Dimens.disabledOpacity : Dimens.enabledOpacity,
|
||||||
child: const Column(
|
child: Column(
|
||||||
children: [
|
children: switch (state.profile) {
|
||||||
_NameFieldBuilder(),
|
EquipmentProfile() => [
|
||||||
_IsoValuesListTileBuilder(),
|
_NameFieldBuilder<T>(),
|
||||||
_NdValuesListTileBuilder(),
|
_ApertureValuesListTileBuilder(),
|
||||||
_ApertureValuesListTileBuilder(),
|
_ShutterSpeedValuesListTileBuilder(),
|
||||||
_ShutterSpeedValuesListTileBuilder(),
|
_IsoValuesListTileBuilder<T>(),
|
||||||
_LensZoomListTileBuilder(),
|
_NdValuesListTileBuilder(),
|
||||||
_ExposureOffsetListTileBuilder(),
|
_LensZoomListTileBuilder<T>(),
|
||||||
],
|
_ExposureOffsetListTileBuilder<T>(),
|
||||||
|
],
|
||||||
|
PinholeEquipmentProfile() => [
|
||||||
|
_NameFieldBuilder<T>(),
|
||||||
|
// TODO: Add aperture value list tile for pinhole equipment profile
|
||||||
|
_IsoValuesListTileBuilder<T>(),
|
||||||
|
_LensZoomListTileBuilder<T>(),
|
||||||
|
_ExposureOffsetListTileBuilder<T>(),
|
||||||
|
],
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -126,12 +135,13 @@ class _EquipmentProfileEditScreenState extends State<EquipmentProfileEditScreen>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _NameFieldBuilder extends StatelessWidget {
|
class _NameFieldBuilder<T extends IEquipmentProfile> extends StatelessWidget {
|
||||||
const _NameFieldBuilder();
|
const _NameFieldBuilder();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
return BlocBuilder<IEquipmentProfileEditBloc<T>, EquipmentProfileEditState<T>>(
|
||||||
|
buildWhen: (previous, current) => previous.profile.name != current.profile.name,
|
||||||
builder: (context, state) => Padding(
|
builder: (context, state) => Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
left: Dimens.paddingM,
|
left: Dimens.paddingM,
|
||||||
|
@ -141,13 +151,13 @@ class _NameFieldBuilder extends StatelessWidget {
|
||||||
),
|
),
|
||||||
child: LightmeterTextField(
|
child: LightmeterTextField(
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
initialValue: state.name,
|
initialValue: state.profile.name,
|
||||||
maxLength: 48,
|
maxLength: 48,
|
||||||
hintText: S.of(context).name,
|
hintText: S.of(context).name,
|
||||||
style: Theme.of(context).listTileTheme.titleTextStyle,
|
style: Theme.of(context).listTileTheme.titleTextStyle,
|
||||||
leading: const Icon(Icons.edit_outlined),
|
leading: const Icon(Icons.edit_outlined),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context.read<EquipmentProfileEditBloc>().add(EquipmentProfileNameChangedEvent(value));
|
context.read<IEquipmentProfileEditBloc<T>>().add(EquipmentProfileNameChangedEvent<T>(value));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -155,20 +165,20 @@ class _NameFieldBuilder extends StatelessWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _IsoValuesListTileBuilder extends StatelessWidget {
|
class _IsoValuesListTileBuilder<T extends IEquipmentProfile> extends StatelessWidget {
|
||||||
const _IsoValuesListTileBuilder();
|
const _IsoValuesListTileBuilder();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
return BlocBuilder<IEquipmentProfileEditBloc<T>, EquipmentProfileEditState<T>>(
|
||||||
builder: (context, state) => FilterListTile<IsoValue>(
|
builder: (context, state) => FilterListTile<IsoValue>(
|
||||||
icon: Icons.iso_outlined,
|
icon: Icons.iso_outlined,
|
||||||
title: S.of(context).isoValues,
|
title: S.of(context).isoValues,
|
||||||
description: S.of(context).isoValuesFilterDescription,
|
description: S.of(context).isoValuesFilterDescription,
|
||||||
values: IsoValue.values,
|
values: IsoValue.values,
|
||||||
selectedValues: state.isoValues,
|
selectedValues: state.profile.isoValues,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context.read<EquipmentProfileEditBloc>().add(EquipmentProfileIsoValuesChangedEvent(value));
|
context.read<IEquipmentProfileEditBloc<T>>().add(EquipmentProfileIsoValuesChangedEvent<T>(value));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -180,13 +190,13 @@ class _NdValuesListTileBuilder extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
return BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState<EquipmentProfile>>(
|
||||||
builder: (context, state) => FilterListTile<NdValue>(
|
builder: (context, state) => FilterListTile<NdValue>(
|
||||||
icon: Icons.filter_b_and_w_outlined,
|
icon: Icons.filter_b_and_w_outlined,
|
||||||
title: S.of(context).ndFilters,
|
title: S.of(context).ndFilters,
|
||||||
description: S.of(context).ndFiltersFilterDescription,
|
description: S.of(context).ndFiltersFilterDescription,
|
||||||
values: NdValue.values,
|
values: NdValue.values,
|
||||||
selectedValues: state.ndValues,
|
selectedValues: state.profile.ndValues,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context.read<EquipmentProfileEditBloc>().add(EquipmentProfileNdValuesChangedEvent(value));
|
context.read<EquipmentProfileEditBloc>().add(EquipmentProfileNdValuesChangedEvent(value));
|
||||||
},
|
},
|
||||||
|
@ -200,13 +210,13 @@ class _ApertureValuesListTileBuilder extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
return BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState<EquipmentProfile>>(
|
||||||
builder: (context, state) => RangePickerListTile<ApertureValue>(
|
builder: (context, state) => RangePickerListTile<ApertureValue>(
|
||||||
icon: Icons.camera_outlined,
|
icon: Icons.camera_outlined,
|
||||||
title: S.of(context).apertureValues,
|
title: S.of(context).apertureValues,
|
||||||
description: S.of(context).apertureValuesFilterDescription,
|
description: S.of(context).apertureValuesFilterDescription,
|
||||||
values: ApertureValue.values,
|
values: ApertureValue.values,
|
||||||
selectedValues: state.apertureValues,
|
selectedValues: state.profile.apertureValues,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context.read<EquipmentProfileEditBloc>().add(EquipmentProfileApertureValuesChangedEvent(value));
|
context.read<EquipmentProfileEditBloc>().add(EquipmentProfileApertureValuesChangedEvent(value));
|
||||||
},
|
},
|
||||||
|
@ -220,13 +230,13 @@ class _ShutterSpeedValuesListTileBuilder extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
return BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState<EquipmentProfile>>(
|
||||||
builder: (context, state) => RangePickerListTile<ShutterSpeedValue>(
|
builder: (context, state) => RangePickerListTile<ShutterSpeedValue>(
|
||||||
icon: Icons.shutter_speed_outlined,
|
icon: Icons.shutter_speed_outlined,
|
||||||
title: S.of(context).shutterSpeedValues,
|
title: S.of(context).shutterSpeedValues,
|
||||||
description: S.of(context).shutterSpeedValuesFilterDescription,
|
description: S.of(context).shutterSpeedValuesFilterDescription,
|
||||||
values: ShutterSpeedValue.values,
|
values: ShutterSpeedValue.values,
|
||||||
selectedValues: state.shutterSpeedValues,
|
selectedValues: state.profile.shutterSpeedValues,
|
||||||
trailingAdapter: (context, value) =>
|
trailingAdapter: (context, value) =>
|
||||||
value.value == 1 ? S.of(context).shutterSpeedManualShort : value.toString(),
|
value.value == 1 ? S.of(context).shutterSpeedManualShort : value.toString(),
|
||||||
dialogValueAdapter: (context, value) => value.value == 1 ? S.of(context).shutterSpeedManual : value.toString(),
|
dialogValueAdapter: (context, value) => value.value == 1 ? S.of(context).shutterSpeedManual : value.toString(),
|
||||||
|
@ -238,42 +248,44 @@ class _ShutterSpeedValuesListTileBuilder extends StatelessWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _LensZoomListTileBuilder extends StatelessWidget {
|
class _LensZoomListTileBuilder<T extends IEquipmentProfile> extends StatelessWidget {
|
||||||
const _LensZoomListTileBuilder();
|
const _LensZoomListTileBuilder();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
return BlocBuilder<IEquipmentProfileEditBloc<T>, EquipmentProfileEditState<T>>(
|
||||||
|
buildWhen: (previous, current) => previous.profile.lensZoom != current.profile.lensZoom,
|
||||||
builder: (context, state) => SliderPickerListTile(
|
builder: (context, state) => SliderPickerListTile(
|
||||||
icon: Icons.zoom_in_outlined,
|
icon: Icons.zoom_in_outlined,
|
||||||
title: S.of(context).lensZoom,
|
title: S.of(context).lensZoom,
|
||||||
description: S.of(context).lensZoomDescription,
|
description: S.of(context).lensZoomDescription,
|
||||||
value: state.lensZoom,
|
value: state.profile.lensZoom,
|
||||||
range: CameraContainerBloc.zoomMaxRange,
|
range: CameraContainerBloc.zoomMaxRange,
|
||||||
valueAdapter: (context, value) => value.toZoom(context),
|
valueAdapter: (context, value) => value.toZoom(context),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context.read<EquipmentProfileEditBloc>().add(EquipmentProfileLensZoomChangedEvent(value));
|
context.read<IEquipmentProfileEditBloc<T>>().add(EquipmentProfileLensZoomChangedEvent<T>(value));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ExposureOffsetListTileBuilder extends StatelessWidget {
|
class _ExposureOffsetListTileBuilder<T extends IEquipmentProfile> extends StatelessWidget {
|
||||||
const _ExposureOffsetListTileBuilder();
|
const _ExposureOffsetListTileBuilder();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
return BlocBuilder<IEquipmentProfileEditBloc<T>, EquipmentProfileEditState<T>>(
|
||||||
|
buildWhen: (previous, current) => previous.profile.exposureOffset != current.profile.exposureOffset,
|
||||||
builder: (context, state) => SliderPickerListTile(
|
builder: (context, state) => SliderPickerListTile(
|
||||||
icon: Icons.light_mode_outlined,
|
icon: Icons.light_mode_outlined,
|
||||||
title: S.of(context).exposureOffset,
|
title: S.of(context).exposureOffset,
|
||||||
description: S.of(context).exposureOffsetDescription,
|
description: S.of(context).exposureOffsetDescription,
|
||||||
value: state.exposureOffset,
|
value: state.profile.exposureOffset,
|
||||||
range: CameraContainerBloc.exposureMaxRange,
|
range: CameraContainerBloc.exposureMaxRange,
|
||||||
valueAdapter: (context, value) => S.of(context).evValue(value.toStringSignedAsFixed(1)),
|
valueAdapter: (context, value) => S.of(context).evValue(value.toStringSignedAsFixed(1)),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context.read<EquipmentProfileEditBloc>().add(EquipmentProfileExposureOffsetChangedEvent(value));
|
context.read<IEquipmentProfileEditBloc<T>>().add(EquipmentProfileExposureOffsetChangedEvent<T>(value));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,52 +1,28 @@
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
class EquipmentProfileEditState {
|
class EquipmentProfileEditState<T extends IEquipmentProfile> {
|
||||||
final String name;
|
final T profile;
|
||||||
final List<ApertureValue> apertureValues;
|
final T? profileToCopy;
|
||||||
final List<NdValue> ndValues;
|
|
||||||
final List<ShutterSpeedValue> shutterSpeedValues;
|
|
||||||
final List<IsoValue> isoValues;
|
|
||||||
final double lensZoom;
|
|
||||||
final double exposureOffset;
|
|
||||||
final bool canSave;
|
final bool canSave;
|
||||||
final bool isLoading;
|
final bool isLoading;
|
||||||
final EquipmentProfile? profileToCopy;
|
|
||||||
|
|
||||||
const EquipmentProfileEditState({
|
const EquipmentProfileEditState({
|
||||||
required this.name,
|
required this.profile,
|
||||||
required this.apertureValues,
|
|
||||||
required this.ndValues,
|
|
||||||
required this.shutterSpeedValues,
|
|
||||||
required this.isoValues,
|
|
||||||
required this.lensZoom,
|
|
||||||
required this.exposureOffset,
|
|
||||||
required this.canSave,
|
required this.canSave,
|
||||||
this.isLoading = false,
|
this.isLoading = false,
|
||||||
this.profileToCopy,
|
this.profileToCopy,
|
||||||
});
|
});
|
||||||
|
|
||||||
EquipmentProfileEditState copyWith({
|
EquipmentProfileEditState<T> copyWith({
|
||||||
String? name,
|
T? profile,
|
||||||
List<ApertureValue>? apertureValues,
|
T? profileToCopy,
|
||||||
List<NdValue>? ndValues,
|
|
||||||
List<ShutterSpeedValue>? shutterSpeedValues,
|
|
||||||
List<IsoValue>? isoValues,
|
|
||||||
double? lensZoom,
|
|
||||||
double? exposureOffset,
|
|
||||||
bool? canSave,
|
bool? canSave,
|
||||||
bool? isLoading,
|
bool? isLoading,
|
||||||
EquipmentProfile? profileToCopy,
|
|
||||||
}) =>
|
}) =>
|
||||||
EquipmentProfileEditState(
|
EquipmentProfileEditState<T>(
|
||||||
name: name ?? this.name,
|
profile: profile ?? this.profile,
|
||||||
apertureValues: apertureValues ?? this.apertureValues,
|
profileToCopy: profileToCopy ?? this.profileToCopy,
|
||||||
ndValues: ndValues ?? this.ndValues,
|
|
||||||
shutterSpeedValues: shutterSpeedValues ?? this.shutterSpeedValues,
|
|
||||||
isoValues: isoValues ?? this.isoValues,
|
|
||||||
lensZoom: lensZoom ?? this.lensZoom,
|
|
||||||
exposureOffset: exposureOffset ?? this.exposureOffset,
|
|
||||||
canSave: canSave ?? this.canSave,
|
canSave: canSave ?? this.canSave,
|
||||||
isLoading: isLoading ?? this.isLoading,
|
isLoading: isLoading ?? this.isLoading,
|
||||||
profileToCopy: profileToCopy ?? this.profileToCopy,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,14 @@ import 'package:lightmeter/navigation/routes.dart';
|
||||||
import 'package:lightmeter/providers/equipment_profile_provider.dart';
|
import 'package:lightmeter/providers/equipment_profile_provider.dart';
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
import 'package:lightmeter/res/dimens.dart';
|
||||||
import 'package:lightmeter/screens/equipment_profile_edit/flow_equipment_profile_edit.dart';
|
import 'package:lightmeter/screens/equipment_profile_edit/flow_equipment_profile_edit.dart';
|
||||||
|
import 'package:lightmeter/screens/settings/components/shared/dialog_picker/widget_dialog_picker.dart';
|
||||||
import 'package:lightmeter/screens/shared/sliver_placeholder/widget_sliver_placeholder.dart';
|
import 'package:lightmeter/screens/shared/sliver_placeholder/widget_sliver_placeholder.dart';
|
||||||
import 'package:lightmeter/screens/shared/sliver_screen/screen_sliver.dart';
|
import 'package:lightmeter/screens/shared/sliver_screen/screen_sliver.dart';
|
||||||
import 'package:lightmeter/utils/guard_pro_tap.dart';
|
import 'package:lightmeter/utils/guard_pro_tap.dart';
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
|
enum _EquipmentProfileType { regular, pinhole }
|
||||||
|
|
||||||
class EquipmentProfilesScreen extends StatefulWidget {
|
class EquipmentProfilesScreen extends StatefulWidget {
|
||||||
const EquipmentProfilesScreen({super.key});
|
const EquipmentProfilesScreen({super.key});
|
||||||
|
|
||||||
|
@ -45,15 +48,45 @@ class _EquipmentProfilesScreenState extends State<EquipmentProfilesScreen> with
|
||||||
guardProTap(
|
guardProTap(
|
||||||
context,
|
context,
|
||||||
() {
|
() {
|
||||||
Navigator.of(context).pushNamed(
|
showDialog<_EquipmentProfileType>(
|
||||||
NavigationRoutes.equipmentProfileEditScreen.name,
|
context: context,
|
||||||
arguments: const EquipmentProfileEditArgs(editType: EquipmentProfileEditType.add),
|
builder: (_) => DialogPicker<_EquipmentProfileType>(
|
||||||
);
|
icon: Icons.camera_alt_outlined,
|
||||||
|
title: S.of(context).equipmentProfileType,
|
||||||
|
selectedValue: _EquipmentProfileType.regular,
|
||||||
|
values: _EquipmentProfileType.values,
|
||||||
|
titleAdapter: (context, value) => switch (value) {
|
||||||
|
_EquipmentProfileType.regular => S.of(context).camera,
|
||||||
|
_EquipmentProfileType.pinhole => S.of(context).pinholeCamera,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
).then((value) {
|
||||||
|
if (value != null && mounted) {
|
||||||
|
Navigator.of(context).pushNamed(
|
||||||
|
NavigationRoutes.equipmentProfileEditScreen.name,
|
||||||
|
arguments: switch (value) {
|
||||||
|
_EquipmentProfileType.regular => const EquipmentProfileEditArgs(
|
||||||
|
editType: EquipmentProfileEditType.add,
|
||||||
|
profile: EquipmentProfilesProvider.defaultProfile,
|
||||||
|
),
|
||||||
|
_EquipmentProfileType.pinhole => EquipmentProfileEditArgs(
|
||||||
|
editType: EquipmentProfileEditType.add,
|
||||||
|
profile: PinholeEquipmentProfile(
|
||||||
|
id: EquipmentProfilesProvider.defaultProfile.id,
|
||||||
|
name: EquipmentProfilesProvider.defaultProfile.name,
|
||||||
|
aperture: 22,
|
||||||
|
isoValues: EquipmentProfilesProvider.defaultProfile.isoValues,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _editProfile(EquipmentProfile profile) {
|
void _editProfile(IEquipmentProfile profile) {
|
||||||
Navigator.of(context).pushNamed(
|
Navigator.of(context).pushNamed(
|
||||||
NavigationRoutes.equipmentProfileEditScreen.name,
|
NavigationRoutes.equipmentProfileEditScreen.name,
|
||||||
arguments: EquipmentProfileEditArgs(
|
arguments: EquipmentProfileEditArgs(
|
||||||
|
@ -65,9 +98,9 @@ class _EquipmentProfilesScreenState extends State<EquipmentProfilesScreen> with
|
||||||
}
|
}
|
||||||
|
|
||||||
class _EquipmentProfilesListBuilder extends StatelessWidget {
|
class _EquipmentProfilesListBuilder extends StatelessWidget {
|
||||||
final List<EquipmentProfile> values;
|
final List<IEquipmentProfile> values;
|
||||||
final void Function(EquipmentProfile profile) onEdit;
|
final void Function(IEquipmentProfile profile) onEdit;
|
||||||
final void Function(EquipmentProfile profile, bool value) onCheckbox;
|
final void Function(String id, bool value) onCheckbox;
|
||||||
|
|
||||||
const _EquipmentProfilesListBuilder({
|
const _EquipmentProfilesListBuilder({
|
||||||
required this.values,
|
required this.values,
|
||||||
|
@ -102,7 +135,7 @@ class _EquipmentProfilesListBuilder extends StatelessWidget {
|
||||||
title: Text(values[index].name),
|
title: Text(values[index].name),
|
||||||
controlAffinity: ListTileControlAffinity.leading,
|
controlAffinity: ListTileControlAffinity.leading,
|
||||||
value: EquipmentProfiles.inUseOf(context).contains(values[index]),
|
value: EquipmentProfiles.inUseOf(context).contains(values[index]),
|
||||||
onChanged: (value) => onCheckbox(values[index], value ?? false),
|
onChanged: (value) => onCheckbox(values[index].id, value ?? false),
|
||||||
secondary: IconButton(
|
secondary: IconButton(
|
||||||
onPressed: () => onEdit(values[index]),
|
onPressed: () => onEdit(values[index]),
|
||||||
icon: const Icon(Icons.edit_outlined),
|
icon: const Icon(Icons.edit_outlined),
|
||||||
|
|
Loading…
Reference in a new issue