mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2025-09-18 13:56:39 +00:00
discard aperture when unselecting a pinhole profile
This commit is contained in:
parent
232a9316cd
commit
c40354c62b
7 changed files with 67 additions and 39 deletions
|
@ -12,8 +12,15 @@ class LogbookPhotoEditBloc extends Bloc<LogbookPhotoEditEvent, LogbookPhotoEditS
|
||||||
LogbookPhotoEditBloc(
|
LogbookPhotoEditBloc(
|
||||||
this.photosProvider,
|
this.photosProvider,
|
||||||
LogbookPhoto photo,
|
LogbookPhoto photo,
|
||||||
|
IEquipmentProfile? equipmentProfile,
|
||||||
) : _originalPhoto = photo,
|
) : _originalPhoto = photo,
|
||||||
_newPhoto = photo,
|
_newPhoto = photo,
|
||||||
|
assert(
|
||||||
|
equipmentProfile == null ||
|
||||||
|
equipmentProfile is! PinholeEquipmentProfile ||
|
||||||
|
photo.apertureValue != null && equipmentProfile.aperture == photo.apertureValue!.rawValue,
|
||||||
|
"Aperture value must be the same as the equipment profile's aperture value if the equipment profile is a pinhole profile",
|
||||||
|
),
|
||||||
super(
|
super(
|
||||||
LogbookPhotoEditState(
|
LogbookPhotoEditState(
|
||||||
id: photo.id,
|
id: photo.id,
|
||||||
|
@ -25,7 +32,7 @@ class LogbookPhotoEditBloc extends Bloc<LogbookPhotoEditEvent, LogbookPhotoEditS
|
||||||
coordinates: photo.coordinates,
|
coordinates: photo.coordinates,
|
||||||
aperture: photo.apertureValue,
|
aperture: photo.apertureValue,
|
||||||
shutterSpeed: photo.shutterSpeedValue,
|
shutterSpeed: photo.shutterSpeedValue,
|
||||||
equipmentProfileId: photo.equipmentProfileId,
|
equipmentProfile: equipmentProfile,
|
||||||
filmId: photo.filmId,
|
filmId: photo.filmId,
|
||||||
note: photo.note,
|
note: photo.note,
|
||||||
canSave: false,
|
canSave: false,
|
||||||
|
@ -74,10 +81,22 @@ class LogbookPhotoEditBloc extends Bloc<LogbookPhotoEditEvent, LogbookPhotoEditS
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onEquipmentProfileChanged(LogbookPhotoEquipmentProfileChangedEvent event, Emitter emit) async {
|
Future<void> _onEquipmentProfileChanged(LogbookPhotoEquipmentProfileChangedEvent event, Emitter emit) async {
|
||||||
_newPhoto = _newPhoto.copyWith(equipmentProfileId: Optional(event.equipmentProfileId));
|
final equipmentProfile = event.equipmentProfile;
|
||||||
|
Optional<ApertureValue>? apertureValue;
|
||||||
|
if (state.equipmentProfile is PinholeEquipmentProfile &&
|
||||||
|
(equipmentProfile == null || equipmentProfile is EquipmentProfile)) {
|
||||||
|
apertureValue = const Optional(null);
|
||||||
|
} else if (equipmentProfile is PinholeEquipmentProfile) {
|
||||||
|
apertureValue = Optional(ApertureValue(equipmentProfile.aperture, StopType.full));
|
||||||
|
}
|
||||||
|
_newPhoto = _newPhoto.copyWith(
|
||||||
|
apertureValue: apertureValue,
|
||||||
|
equipmentProfileId: Optional(equipmentProfile?.id),
|
||||||
|
);
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
equipmentProfileId: Optional(event.equipmentProfileId),
|
aperture: apertureValue,
|
||||||
|
equipmentProfile: Optional(event.equipmentProfile),
|
||||||
canSave: _canSave(),
|
canSave: _canSave(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,7 +9,7 @@ class PickerListTile<T> extends StatelessWidget {
|
||||||
final T? selectedValue;
|
final T? selectedValue;
|
||||||
final List<T> values;
|
final List<T> values;
|
||||||
final String Function(T) titleAdapter;
|
final String Function(T) titleAdapter;
|
||||||
final ValueChanged<Optional<T>> onChanged;
|
final ValueChanged<Optional<T>>? onChanged;
|
||||||
|
|
||||||
const PickerListTile({
|
const PickerListTile({
|
||||||
required this.icon,
|
required this.icon,
|
||||||
|
@ -27,27 +27,29 @@ class PickerListTile<T> extends StatelessWidget {
|
||||||
leading: Icon(icon),
|
leading: Icon(icon),
|
||||||
title: Text(title),
|
title: Text(title),
|
||||||
trailing: Text(_titleAdapter(context, selectedValue)),
|
trailing: Text(_titleAdapter(context, selectedValue)),
|
||||||
onTap: () {
|
onTap: onChanged != null
|
||||||
showDialog<Optional<T>>(
|
? () {
|
||||||
context: context,
|
showDialog<Optional<T>>(
|
||||||
builder: (_) => DialogPicker<Optional<T>>(
|
context: context,
|
||||||
icon: icon,
|
builder: (_) => DialogPicker<Optional<T>>(
|
||||||
title: title,
|
icon: icon,
|
||||||
selectedValue: Optional(selectedValue),
|
title: title,
|
||||||
values: [
|
selectedValue: Optional(selectedValue),
|
||||||
/// `const Optional(null)` for some reason is not equal to a non-const `Optional(null)`
|
values: [
|
||||||
// ignore: prefer_const_constructors
|
/// `const Optional(null)` for some reason is not equal to a non-const `Optional(null)`
|
||||||
Optional(null),
|
// ignore: prefer_const_constructors
|
||||||
...values.toSet().map((e) => Optional(e)),
|
Optional(null),
|
||||||
],
|
...values.toSet().map((e) => Optional(e)),
|
||||||
titleAdapter: (context, value) => _titleAdapter(context, value.value),
|
],
|
||||||
),
|
titleAdapter: (context, value) => _titleAdapter(context, value.value),
|
||||||
).then((value) {
|
),
|
||||||
if (value != null) {
|
).then((value) {
|
||||||
onChanged(value);
|
if (value != null) {
|
||||||
}
|
onChanged!(value);
|
||||||
});
|
}
|
||||||
},
|
});
|
||||||
|
}
|
||||||
|
: null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,9 @@ class LogbookPhotoNoteChangedEvent extends LogbookPhotoEditEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
class LogbookPhotoEquipmentProfileChangedEvent extends LogbookPhotoEditEvent {
|
class LogbookPhotoEquipmentProfileChangedEvent extends LogbookPhotoEditEvent {
|
||||||
final String? equipmentProfileId;
|
final IEquipmentProfile? equipmentProfile;
|
||||||
|
|
||||||
const LogbookPhotoEquipmentProfileChangedEvent(this.equipmentProfileId);
|
const LogbookPhotoEquipmentProfileChangedEvent(this.equipmentProfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
class LogbookPhotoFilmChangedEvent extends LogbookPhotoEditEvent {
|
class LogbookPhotoFilmChangedEvent extends LogbookPhotoEditEvent {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
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/logbook_photos_provider.dart';
|
import 'package:lightmeter/providers/logbook_photos_provider.dart';
|
||||||
import 'package:lightmeter/screens/logbook_photo_edit/bloc_logbook_photo_edit.dart';
|
import 'package:lightmeter/screens/logbook_photo_edit/bloc_logbook_photo_edit.dart';
|
||||||
import 'package:lightmeter/screens/logbook_photo_edit/screen_logbook_photo_edit.dart';
|
import 'package:lightmeter/screens/logbook_photo_edit/screen_logbook_photo_edit.dart';
|
||||||
|
@ -25,6 +27,7 @@ class LogbookPhotoEditFlow extends StatelessWidget {
|
||||||
create: (_) => LogbookPhotoEditBloc(
|
create: (_) => LogbookPhotoEditBloc(
|
||||||
LogbookPhotosProvider.of(context),
|
LogbookPhotosProvider.of(context),
|
||||||
args.photo,
|
args.photo,
|
||||||
|
EquipmentProfiles.of(context).firstWhereOrNull((e) => e.id == args.photo.equipmentProfileId),
|
||||||
),
|
),
|
||||||
child: const LogbookPhotoEditScreen(),
|
child: const LogbookPhotoEditScreen(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -224,15 +224,17 @@ class _AperturePickerListTile extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<LogbookPhotoEditBloc, LogbookPhotoEditState>(
|
return BlocBuilder<LogbookPhotoEditBloc, LogbookPhotoEditState>(
|
||||||
buildWhen: (previous, current) => previous.aperture != current.aperture,
|
buildWhen: (previous, current) => previous.aperture != current.aperture,
|
||||||
builder: (context, state) => PickerListTile(
|
builder: (context, state) => PickerListTile<ApertureValue>(
|
||||||
icon: Icons.camera_outlined,
|
icon: Icons.camera_outlined,
|
||||||
title: S.of(context).apertureValue,
|
title: S.of(context).apertureValue,
|
||||||
values: ApertureValue.values,
|
values: ApertureValue.values,
|
||||||
selectedValue: state.aperture,
|
selectedValue: state.aperture,
|
||||||
titleAdapter: (value) => value.toString(),
|
titleAdapter: (value) => value.toString(),
|
||||||
onChanged: (value) {
|
onChanged: state.equipmentProfile is PinholeEquipmentProfile
|
||||||
context.read<LogbookPhotoEditBloc>().add(LogbookPhotoApertureChangedEvent(value.value));
|
? null
|
||||||
},
|
: (value) {
|
||||||
|
context.read<LogbookPhotoEditBloc>().add(LogbookPhotoApertureChangedEvent(value.value));
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -265,15 +267,15 @@ class _EquipmentProfilePickerListTile extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<LogbookPhotoEditBloc, LogbookPhotoEditState>(
|
return BlocBuilder<LogbookPhotoEditBloc, LogbookPhotoEditState>(
|
||||||
buildWhen: (previous, current) => previous.equipmentProfileId != current.equipmentProfileId,
|
buildWhen: (previous, current) => previous.equipmentProfile != current.equipmentProfile,
|
||||||
builder: (context, state) => PickerListTile(
|
builder: (context, state) => PickerListTile(
|
||||||
icon: Icons.camera_alt_outlined,
|
icon: Icons.camera_alt_outlined,
|
||||||
title: S.of(context).equipmentProfile,
|
title: S.of(context).equipmentProfile,
|
||||||
values: EquipmentProfiles.of(context).skip(1).toList(growable: false),
|
values: EquipmentProfiles.of(context).skip(1).toList(growable: false),
|
||||||
selectedValue: EquipmentProfiles.of(context).firstWhereOrNull((e) => e.id == state.equipmentProfileId),
|
selectedValue: state.equipmentProfile,
|
||||||
titleAdapter: (value) => value.name,
|
titleAdapter: (value) => value.name,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context.read<LogbookPhotoEditBloc>().add(LogbookPhotoEquipmentProfileChangedEvent(value.value?.id));
|
context.read<LogbookPhotoEditBloc>().add(LogbookPhotoEquipmentProfileChangedEvent(value.value));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -10,7 +10,7 @@ class LogbookPhotoEditState {
|
||||||
final Coordinates? coordinates;
|
final Coordinates? coordinates;
|
||||||
final ApertureValue? aperture;
|
final ApertureValue? aperture;
|
||||||
final ShutterSpeedValue? shutterSpeed;
|
final ShutterSpeedValue? shutterSpeed;
|
||||||
final String? equipmentProfileId;
|
final IEquipmentProfile? equipmentProfile;
|
||||||
final String? filmId;
|
final String? filmId;
|
||||||
final String? note;
|
final String? note;
|
||||||
final bool canSave;
|
final bool canSave;
|
||||||
|
@ -26,7 +26,7 @@ class LogbookPhotoEditState {
|
||||||
this.coordinates,
|
this.coordinates,
|
||||||
this.aperture,
|
this.aperture,
|
||||||
this.shutterSpeed,
|
this.shutterSpeed,
|
||||||
this.equipmentProfileId,
|
this.equipmentProfile,
|
||||||
this.filmId,
|
this.filmId,
|
||||||
this.note,
|
this.note,
|
||||||
required this.canSave,
|
required this.canSave,
|
||||||
|
@ -37,7 +37,7 @@ class LogbookPhotoEditState {
|
||||||
String? name,
|
String? name,
|
||||||
Optional<ApertureValue>? aperture,
|
Optional<ApertureValue>? aperture,
|
||||||
Optional<ShutterSpeedValue>? shutterSpeed,
|
Optional<ShutterSpeedValue>? shutterSpeed,
|
||||||
Optional<String>? equipmentProfileId,
|
Optional<IEquipmentProfile>? equipmentProfile,
|
||||||
Optional<String>? filmId,
|
Optional<String>? filmId,
|
||||||
String? note,
|
String? note,
|
||||||
bool? canSave,
|
bool? canSave,
|
||||||
|
@ -52,7 +52,7 @@ class LogbookPhotoEditState {
|
||||||
nd: nd,
|
nd: nd,
|
||||||
aperture: aperture != null ? aperture.value : this.aperture,
|
aperture: aperture != null ? aperture.value : this.aperture,
|
||||||
shutterSpeed: shutterSpeed != null ? shutterSpeed.value : this.shutterSpeed,
|
shutterSpeed: shutterSpeed != null ? shutterSpeed.value : this.shutterSpeed,
|
||||||
equipmentProfileId: equipmentProfileId != null ? equipmentProfileId.value : this.equipmentProfileId,
|
equipmentProfile: equipmentProfile != null ? equipmentProfile.value : this.equipmentProfile,
|
||||||
filmId: filmId != null ? filmId.value : this.filmId,
|
filmId: filmId != null ? filmId.value : this.filmId,
|
||||||
note: note ?? this.note,
|
note: note ?? this.note,
|
||||||
canSave: canSave ?? this.canSave,
|
canSave: canSave ?? this.canSave,
|
||||||
|
|
|
@ -26,6 +26,7 @@ class DialogPicker<T> extends StatefulWidget {
|
||||||
class _DialogPickerState<T> extends State<DialogPicker<T>> {
|
class _DialogPickerState<T> extends State<DialogPicker<T>> {
|
||||||
late T _selected = widget.selectedValue;
|
late T _selected = widget.selectedValue;
|
||||||
final ScrollController _scrollController = ScrollController();
|
final ScrollController _scrollController = ScrollController();
|
||||||
|
bool _hasSelection = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
@ -34,6 +35,7 @@ class _DialogPickerState<T> extends State<DialogPicker<T>> {
|
||||||
final selectedIndex = widget.values.indexOf(_selected);
|
final selectedIndex = widget.values.indexOf(_selected);
|
||||||
if (selectedIndex >= 0) {
|
if (selectedIndex >= 0) {
|
||||||
_scrollController.jumpTo((Dimens.grid56 * selectedIndex).clamp(0, _scrollController.position.maxScrollExtent));
|
_scrollController.jumpTo((Dimens.grid56 * selectedIndex).clamp(0, _scrollController.position.maxScrollExtent));
|
||||||
|
_hasSelection = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -93,7 +95,7 @@ class _DialogPickerState<T> extends State<DialogPicker<T>> {
|
||||||
child: Text(S.of(context).cancel),
|
child: Text(S.of(context).cancel),
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(_selected),
|
onPressed: _hasSelection ? () => Navigator.of(context).pop(_selected) : null,
|
||||||
child: Text(S.of(context).select),
|
child: Text(S.of(context).select),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in a new issue