mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2025-08-26 23:16:42 +00:00
added film and equipment profile picker to logbook edit
This commit is contained in:
parent
7abbe51e63
commit
0576059e57
6 changed files with 117 additions and 5 deletions
|
@ -114,6 +114,7 @@ class FilmsProviderState extends State<FilmsProvider> {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum _FilmsModelAspect {
|
enum _FilmsModelAspect {
|
||||||
|
all,
|
||||||
customFilms,
|
customFilms,
|
||||||
predefinedFilms,
|
predefinedFilms,
|
||||||
filmsInUse,
|
filmsInUse,
|
||||||
|
@ -134,6 +135,14 @@ class Films extends InheritedModel<_FilmsModelAspect> {
|
||||||
required super.child,
|
required super.child,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
static List<Film> of<T>(BuildContext context) {
|
||||||
|
final model = InheritedModel.inheritFrom<Films>(context, aspect: _FilmsModelAspect.all)!;
|
||||||
|
return [
|
||||||
|
...model.customFilms.values.map((e) => e.value),
|
||||||
|
...model.predefinedFilms.values.map((e) => e.value),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
static List<Film> predefinedFilmsOf<T>(BuildContext context) {
|
static List<Film> predefinedFilmsOf<T>(BuildContext context) {
|
||||||
return InheritedModel.inheritFrom<Films>(context, aspect: _FilmsModelAspect.predefinedFilms)!
|
return InheritedModel.inheritFrom<Films>(context, aspect: _FilmsModelAspect.predefinedFilms)!
|
||||||
.predefinedFilms
|
.predefinedFilms
|
||||||
|
@ -171,10 +180,12 @@ class Films extends InheritedModel<_FilmsModelAspect> {
|
||||||
bool updateShouldNotifyDependent(Films oldWidget, Set<_FilmsModelAspect> dependencies) {
|
bool updateShouldNotifyDependent(Films oldWidget, Set<_FilmsModelAspect> dependencies) {
|
||||||
return (dependencies.contains(_FilmsModelAspect.selected) && oldWidget.selected != selected) ||
|
return (dependencies.contains(_FilmsModelAspect.selected) && oldWidget.selected != selected) ||
|
||||||
((dependencies.contains(_FilmsModelAspect.predefinedFilms) ||
|
((dependencies.contains(_FilmsModelAspect.predefinedFilms) ||
|
||||||
dependencies.contains(_FilmsModelAspect.filmsInUse)) &&
|
dependencies.contains(_FilmsModelAspect.filmsInUse) ||
|
||||||
|
dependencies.contains(_FilmsModelAspect.all)) &&
|
||||||
const DeepCollectionEquality().equals(oldWidget.predefinedFilms, predefinedFilms)) ||
|
const DeepCollectionEquality().equals(oldWidget.predefinedFilms, predefinedFilms)) ||
|
||||||
((dependencies.contains(_FilmsModelAspect.customFilms) ||
|
((dependencies.contains(_FilmsModelAspect.customFilms) ||
|
||||||
dependencies.contains(_FilmsModelAspect.filmsInUse)) &&
|
dependencies.contains(_FilmsModelAspect.filmsInUse) ||
|
||||||
|
dependencies.contains(_FilmsModelAspect.all)) &&
|
||||||
const DeepCollectionEquality().equals(oldWidget.customFilms, customFilms));
|
const DeepCollectionEquality().equals(oldWidget.customFilms, customFilms));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ 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,
|
||||||
|
filmId: photo.filmId,
|
||||||
note: photo.note,
|
note: photo.note,
|
||||||
canSave: false,
|
canSave: false,
|
||||||
),
|
),
|
||||||
|
@ -36,6 +38,10 @@ class LogbookPhotoEditBloc extends Bloc<LogbookPhotoEditEvent, LogbookPhotoEditS
|
||||||
await _onApertureChanged(e, emit);
|
await _onApertureChanged(e, emit);
|
||||||
case final LogbookPhotoShutterSpeedChangedEvent e:
|
case final LogbookPhotoShutterSpeedChangedEvent e:
|
||||||
await _onShutterSpeedChanged(e, emit);
|
await _onShutterSpeedChanged(e, emit);
|
||||||
|
case final LogbookPhotoEquipmentProfileChangedEvent e:
|
||||||
|
await _onEquipmentProfileChanged(e, emit);
|
||||||
|
case final LogbookPhotoFilmChangedEvent e:
|
||||||
|
await _onFilmChanged(e, emit);
|
||||||
case final LogbookPhotoNoteChangedEvent e:
|
case final LogbookPhotoNoteChangedEvent e:
|
||||||
await _onNoteChanged(e, emit);
|
await _onNoteChanged(e, emit);
|
||||||
case LogbookPhotoSaveEvent():
|
case LogbookPhotoSaveEvent():
|
||||||
|
@ -67,6 +73,26 @@ class LogbookPhotoEditBloc extends Bloc<LogbookPhotoEditEvent, LogbookPhotoEditS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _onEquipmentProfileChanged(LogbookPhotoEquipmentProfileChangedEvent event, Emitter emit) async {
|
||||||
|
_newPhoto = _newPhoto.copyWith(equipmentProfileId: Optional(event.equipmentProfile?.id));
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
equipmentProfileId: Optional(event.equipmentProfile?.id),
|
||||||
|
canSave: _canSave(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onFilmChanged(LogbookPhotoFilmChangedEvent event, Emitter emit) async {
|
||||||
|
_newPhoto = _newPhoto.copyWith(filmId: Optional(event.film?.id));
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
filmId: Optional(event.film?.id),
|
||||||
|
canSave: _canSave(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _onNoteChanged(LogbookPhotoNoteChangedEvent event, Emitter emit) async {
|
Future<void> _onNoteChanged(LogbookPhotoNoteChangedEvent event, Emitter emit) async {
|
||||||
_newPhoto = _newPhoto.copyWith(note: event.note);
|
_newPhoto = _newPhoto.copyWith(note: event.note);
|
||||||
emit(
|
emit(
|
||||||
|
|
|
@ -3,11 +3,12 @@ import 'package:lightmeter/generated/l10n.dart';
|
||||||
import 'package:lightmeter/screens/settings/components/shared/dialog_picker/widget_dialog_picker.dart';
|
import 'package:lightmeter/screens/settings/components/shared/dialog_picker/widget_dialog_picker.dart';
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
class PickerListTile<T extends PhotographyValue> extends StatelessWidget {
|
class PickerListTile<T> extends StatelessWidget {
|
||||||
final IconData icon;
|
final IconData icon;
|
||||||
final String title;
|
final String title;
|
||||||
final T? selectedValue;
|
final T? selectedValue;
|
||||||
final List<T> values;
|
final List<T> values;
|
||||||
|
final String Function(T) titleAdapter;
|
||||||
final ValueChanged<Optional<T>> onChanged;
|
final ValueChanged<Optional<T>> onChanged;
|
||||||
|
|
||||||
const PickerListTile({
|
const PickerListTile({
|
||||||
|
@ -15,6 +16,7 @@ class PickerListTile<T extends PhotographyValue> extends StatelessWidget {
|
||||||
required this.title,
|
required this.title,
|
||||||
required this.selectedValue,
|
required this.selectedValue,
|
||||||
required this.values,
|
required this.values,
|
||||||
|
required this.titleAdapter,
|
||||||
required this.onChanged,
|
required this.onChanged,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
@ -24,7 +26,7 @@ class PickerListTile<T extends PhotographyValue> extends StatelessWidget {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: Icon(icon),
|
leading: Icon(icon),
|
||||||
title: Text(title),
|
title: Text(title),
|
||||||
trailing: Text(selectedValue?.toString() ?? S.of(context).notSet),
|
trailing: Text(_titleAdapter(context, selectedValue)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
showDialog<Optional<T>>(
|
showDialog<Optional<T>>(
|
||||||
context: context,
|
context: context,
|
||||||
|
@ -36,7 +38,7 @@ class PickerListTile<T extends PhotographyValue> extends StatelessWidget {
|
||||||
const Optional(null),
|
const Optional(null),
|
||||||
...values.toSet().map((e) => Optional(e)),
|
...values.toSet().map((e) => Optional(e)),
|
||||||
],
|
],
|
||||||
titleAdapter: (context, value) => value.value?.toString() ?? S.of(context).notSet,
|
titleAdapter: (context, value) => _titleAdapter(context, value.value),
|
||||||
),
|
),
|
||||||
).then((value) {
|
).then((value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
|
@ -46,4 +48,8 @@ class PickerListTile<T extends PhotographyValue> extends StatelessWidget {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String _titleAdapter(BuildContext context, T? value) {
|
||||||
|
return value != null ? titleAdapter(value) : S.of(context).notSet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,18 @@ class LogbookPhotoNoteChangedEvent extends LogbookPhotoEditEvent {
|
||||||
const LogbookPhotoNoteChangedEvent(this.note);
|
const LogbookPhotoNoteChangedEvent(this.note);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LogbookPhotoEquipmentProfileChangedEvent extends LogbookPhotoEditEvent {
|
||||||
|
final EquipmentProfile? equipmentProfile;
|
||||||
|
|
||||||
|
const LogbookPhotoEquipmentProfileChangedEvent(this.equipmentProfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
class LogbookPhotoFilmChangedEvent extends LogbookPhotoEditEvent {
|
||||||
|
final Film? film;
|
||||||
|
|
||||||
|
const LogbookPhotoFilmChangedEvent(this.film);
|
||||||
|
}
|
||||||
|
|
||||||
class LogbookPhotoSaveEvent extends LogbookPhotoEditEvent {
|
class LogbookPhotoSaveEvent extends LogbookPhotoEditEvent {
|
||||||
const LogbookPhotoSaveEvent();
|
const LogbookPhotoSaveEvent();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
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/generated/l10n.dart';
|
import 'package:lightmeter/generated/l10n.dart';
|
||||||
import 'package:lightmeter/platform_config.dart';
|
import 'package:lightmeter/platform_config.dart';
|
||||||
|
import 'package:lightmeter/providers/equipment_profile_provider.dart';
|
||||||
|
import 'package:lightmeter/providers/films_provider.dart';
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
import 'package:lightmeter/res/dimens.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/components/coordinates_list_tile/widget_list_tile_coordinates_logbook_photo.dart';
|
import 'package:lightmeter/screens/logbook_photo_edit/components/coordinates_list_tile/widget_list_tile_coordinates_logbook_photo.dart';
|
||||||
|
@ -73,6 +76,8 @@ class _LogbookPhotoEditScreenState extends State<LogbookPhotoEditScreen> {
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
LogbookPhotoCoordinatesListTile(),
|
LogbookPhotoCoordinatesListTile(),
|
||||||
|
_EquipmentProfilePickerListTile(),
|
||||||
|
_FilmPickerListTile(),
|
||||||
_NoteListTile(),
|
_NoteListTile(),
|
||||||
_EvListTile(),
|
_EvListTile(),
|
||||||
_IsoListTile(),
|
_IsoListTile(),
|
||||||
|
@ -224,6 +229,7 @@ class _AperturePickerListTile extends StatelessWidget {
|
||||||
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(),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context.read<LogbookPhotoEditBloc>().add(LogbookPhotoApertureChangedEvent(value.value));
|
context.read<LogbookPhotoEditBloc>().add(LogbookPhotoApertureChangedEvent(value.value));
|
||||||
},
|
},
|
||||||
|
@ -244,6 +250,7 @@ class _ShutterSpeedPickerListTile extends StatelessWidget {
|
||||||
title: S.of(context).shutterSpeedValue,
|
title: S.of(context).shutterSpeedValue,
|
||||||
values: ShutterSpeedValue.values,
|
values: ShutterSpeedValue.values,
|
||||||
selectedValue: state.shutterSpeed,
|
selectedValue: state.shutterSpeed,
|
||||||
|
titleAdapter: (value) => value.toString(),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context.read<LogbookPhotoEditBloc>().add(LogbookPhotoShutterSpeedChangedEvent(value.value));
|
context.read<LogbookPhotoEditBloc>().add(LogbookPhotoShutterSpeedChangedEvent(value.value));
|
||||||
},
|
},
|
||||||
|
@ -251,3 +258,45 @@ class _ShutterSpeedPickerListTile extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _EquipmentProfilePickerListTile extends StatelessWidget {
|
||||||
|
const _EquipmentProfilePickerListTile();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<LogbookPhotoEditBloc, LogbookPhotoEditState>(
|
||||||
|
buildWhen: (previous, current) => previous.equipmentProfileId != current.equipmentProfileId,
|
||||||
|
builder: (context, state) => PickerListTile(
|
||||||
|
icon: Icons.camera_alt_outlined,
|
||||||
|
title: S.of(context).equipmentProfile,
|
||||||
|
values: EquipmentProfiles.of(context),
|
||||||
|
selectedValue: EquipmentProfiles.of(context).firstWhereOrNull((e) => e.id == state.equipmentProfileId),
|
||||||
|
titleAdapter: (value) => value.name,
|
||||||
|
onChanged: (value) {
|
||||||
|
context.read<LogbookPhotoEditBloc>().add(LogbookPhotoEquipmentProfileChangedEvent(value.value));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FilmPickerListTile extends StatelessWidget {
|
||||||
|
const _FilmPickerListTile();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<LogbookPhotoEditBloc, LogbookPhotoEditState>(
|
||||||
|
buildWhen: (previous, current) => previous.filmId != current.filmId,
|
||||||
|
builder: (context, state) => PickerListTile(
|
||||||
|
icon: Icons.camera_roll_outlined,
|
||||||
|
title: S.of(context).film,
|
||||||
|
values: Films.of(context),
|
||||||
|
selectedValue: Films.of(context).firstWhereOrNull((e) => e.id == state.filmId),
|
||||||
|
titleAdapter: (value) => value.name,
|
||||||
|
onChanged: (value) {
|
||||||
|
context.read<LogbookPhotoEditBloc>().add(LogbookPhotoFilmChangedEvent(value.value));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ class LogbookPhotoEditState {
|
||||||
final Coordinates? coordinates;
|
final Coordinates? coordinates;
|
||||||
final ApertureValue? aperture;
|
final ApertureValue? aperture;
|
||||||
final ShutterSpeedValue? shutterSpeed;
|
final ShutterSpeedValue? shutterSpeed;
|
||||||
|
final String? equipmentProfileId;
|
||||||
|
final String? filmId;
|
||||||
final String? note;
|
final String? note;
|
||||||
final bool canSave;
|
final bool canSave;
|
||||||
final bool isLoading;
|
final bool isLoading;
|
||||||
|
@ -24,6 +26,8 @@ class LogbookPhotoEditState {
|
||||||
this.coordinates,
|
this.coordinates,
|
||||||
this.aperture,
|
this.aperture,
|
||||||
this.shutterSpeed,
|
this.shutterSpeed,
|
||||||
|
this.equipmentProfileId,
|
||||||
|
this.filmId,
|
||||||
this.note,
|
this.note,
|
||||||
required this.canSave,
|
required this.canSave,
|
||||||
this.isLoading = false,
|
this.isLoading = false,
|
||||||
|
@ -33,6 +37,8 @@ class LogbookPhotoEditState {
|
||||||
String? name,
|
String? name,
|
||||||
Optional<ApertureValue>? aperture,
|
Optional<ApertureValue>? aperture,
|
||||||
Optional<ShutterSpeedValue>? shutterSpeed,
|
Optional<ShutterSpeedValue>? shutterSpeed,
|
||||||
|
Optional<String>? equipmentProfileId,
|
||||||
|
Optional<String>? filmId,
|
||||||
String? note,
|
String? note,
|
||||||
bool? canSave,
|
bool? canSave,
|
||||||
bool? isLoading,
|
bool? isLoading,
|
||||||
|
@ -46,6 +52,8 @@ 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,
|
||||||
|
filmId: filmId != null ? filmId.value : this.filmId,
|
||||||
note: note ?? this.note,
|
note: note ?? this.note,
|
||||||
canSave: canSave ?? this.canSave,
|
canSave: canSave ?? this.canSave,
|
||||||
isLoading: isLoading ?? this.isLoading,
|
isLoading: isLoading ?? this.isLoading,
|
||||||
|
|
Loading…
Reference in a new issue