mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-25 00:40:39 +00:00
implemented EquipmentProfileEditScreen
This commit is contained in:
parent
5ddaed8dfb
commit
1d0d901218
12 changed files with 523 additions and 128 deletions
|
@ -160,5 +160,7 @@
|
||||||
"filmFormulaExponential": "T=t^Rf",
|
"filmFormulaExponential": "T=t^Rf",
|
||||||
"filmFormulaExponentialRf": "Rf",
|
"filmFormulaExponentialRf": "Rf",
|
||||||
"filmFormulaExponentialRfPlaceholder": "1.3",
|
"filmFormulaExponentialRfPlaceholder": "1.3",
|
||||||
"name": "Name"
|
"name": "Name",
|
||||||
|
"addEquipmentProfileTitle": "Add equipment profile",
|
||||||
|
"editEquipmentProfileTitle": "Edit equipment profile"
|
||||||
}
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.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/state_equipment_profile_edit.dart';
|
||||||
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
|
class EquipmentProfileEditBloc extends Bloc<EquipmentProfileEditEvent, EquipmentProfileEditState> {
|
||||||
|
static const EquipmentProfile _defaultProfile = EquipmentProfile(
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
apertureValues: ApertureValue.values,
|
||||||
|
ndValues: NdValue.values,
|
||||||
|
shutterSpeedValues: ShutterSpeedValue.values,
|
||||||
|
isoValues: IsoValue.values,
|
||||||
|
);
|
||||||
|
|
||||||
|
final EquipmentProfileProviderState profilesProvider;
|
||||||
|
final EquipmentProfile _originalEquipmentProfile;
|
||||||
|
EquipmentProfile _newEquipmentProfile;
|
||||||
|
final bool _isEdit;
|
||||||
|
|
||||||
|
factory EquipmentProfileEditBloc(
|
||||||
|
EquipmentProfileProviderState profilesProvider, {
|
||||||
|
required EquipmentProfile? profile,
|
||||||
|
required bool isEdit,
|
||||||
|
}) =>
|
||||||
|
profile != null
|
||||||
|
? EquipmentProfileEditBloc._(
|
||||||
|
profilesProvider,
|
||||||
|
profile,
|
||||||
|
isEdit,
|
||||||
|
)
|
||||||
|
: EquipmentProfileEditBloc._(
|
||||||
|
profilesProvider,
|
||||||
|
_defaultProfile,
|
||||||
|
isEdit,
|
||||||
|
);
|
||||||
|
|
||||||
|
EquipmentProfileEditBloc._(
|
||||||
|
this.profilesProvider,
|
||||||
|
EquipmentProfile profile,
|
||||||
|
this._isEdit,
|
||||||
|
) : _originalEquipmentProfile = profile,
|
||||||
|
_newEquipmentProfile = profile,
|
||||||
|
super(
|
||||||
|
EquipmentProfileEditState(
|
||||||
|
name: profile.name,
|
||||||
|
apertureValues: profile.apertureValues,
|
||||||
|
shutterSpeedValues: profile.shutterSpeedValues,
|
||||||
|
isoValues: profile.isoValues,
|
||||||
|
ndValues: profile.ndValues,
|
||||||
|
lensZoom: profile.lensZoom,
|
||||||
|
canSave: false,
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
on<EquipmentProfileEditEvent>(
|
||||||
|
(event, 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 EquipmentProfileSaveEvent():
|
||||||
|
await _onSave(event, emit);
|
||||||
|
case EquipmentProfileDeleteEvent():
|
||||||
|
await _onDelete(event, emit);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onNameChanged(EquipmentProfileNameChangedEvent event, Emitter emit) async {
|
||||||
|
_newEquipmentProfile = _newEquipmentProfile.copyWith(name: event.name);
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
name: event.name,
|
||||||
|
canSave: _canSave(event.name, state.lensZoom),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onApertureValuesChanged(EquipmentProfileApertureValuesChangedEvent event, Emitter emit) async {
|
||||||
|
_newEquipmentProfile = _newEquipmentProfile.copyWith(apertureValues: event.apertureValues);
|
||||||
|
emit(state.copyWith(apertureValues: event.apertureValues));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onShutterSpeedValuesChanged(EquipmentProfileShutterSpeedValuesChangedEvent event, Emitter emit) async {
|
||||||
|
_newEquipmentProfile = _newEquipmentProfile.copyWith(shutterSpeedValues: event.shutterSpeedValues);
|
||||||
|
emit(state.copyWith(shutterSpeedValues: event.shutterSpeedValues));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onIsoValuesChanged(EquipmentProfileIsoValuesChangedEvent event, Emitter emit) async {
|
||||||
|
_newEquipmentProfile = _newEquipmentProfile.copyWith(isoValues: event.isoValues);
|
||||||
|
emit(state.copyWith(isoValues: event.isoValues));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onNdValuesChanged(EquipmentProfileNdValuesChangedEvent event, Emitter emit) async {
|
||||||
|
_newEquipmentProfile = _newEquipmentProfile.copyWith(ndValues: event.ndValues);
|
||||||
|
emit(state.copyWith(ndValues: event.ndValues));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onLensZoomChanged(EquipmentProfileLensZoomChangedEvent event, Emitter emit) async {
|
||||||
|
_newEquipmentProfile = _newEquipmentProfile.copyWith(lensZoom: event.lensZoom);
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
lensZoom: event.lensZoom,
|
||||||
|
canSave: _canSave(state.name, event.lensZoom),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onSave(EquipmentProfileSaveEvent _, Emitter emit) async {
|
||||||
|
emit(state.copyWith(isLoading: true));
|
||||||
|
if (_isEdit) {
|
||||||
|
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,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
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,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
emit(state.copyWith(isLoading: false));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onDelete(EquipmentProfileDeleteEvent _, Emitter emit) async {
|
||||||
|
emit(state.copyWith(isLoading: true));
|
||||||
|
await profilesProvider.deleteProfile(_newEquipmentProfile);
|
||||||
|
emit(state.copyWith(isLoading: false));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _canSave(String name, double? exponent) {
|
||||||
|
return name.isNotEmpty && exponent != null && _newEquipmentProfile != _originalEquipmentProfile;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
|
sealed class EquipmentProfileEditEvent {
|
||||||
|
const EquipmentProfileEditEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
class EquipmentProfileNameChangedEvent extends EquipmentProfileEditEvent {
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
const EquipmentProfileNameChangedEvent(this.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
class EquipmentProfileIsoValuesChangedEvent extends EquipmentProfileEditEvent {
|
||||||
|
final List<IsoValue> isoValues;
|
||||||
|
|
||||||
|
const EquipmentProfileIsoValuesChangedEvent(this.isoValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
class EquipmentProfileNdValuesChangedEvent extends EquipmentProfileEditEvent {
|
||||||
|
final List<NdValue> ndValues;
|
||||||
|
|
||||||
|
const EquipmentProfileNdValuesChangedEvent(this.ndValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
class EquipmentProfileApertureValuesChangedEvent extends EquipmentProfileEditEvent {
|
||||||
|
final List<ApertureValue> apertureValues;
|
||||||
|
|
||||||
|
const EquipmentProfileApertureValuesChangedEvent(this.apertureValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
class EquipmentProfileShutterSpeedValuesChangedEvent extends EquipmentProfileEditEvent {
|
||||||
|
final List<ShutterSpeedValue> shutterSpeedValues;
|
||||||
|
|
||||||
|
const EquipmentProfileShutterSpeedValuesChangedEvent(this.shutterSpeedValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
class EquipmentProfileLensZoomChangedEvent extends EquipmentProfileEditEvent {
|
||||||
|
final double lensZoom;
|
||||||
|
|
||||||
|
const EquipmentProfileLensZoomChangedEvent(this.lensZoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
class EquipmentProfileSaveEvent extends EquipmentProfileEditEvent {
|
||||||
|
const EquipmentProfileSaveEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
class EquipmentProfileDeleteEvent extends EquipmentProfileEditEvent {
|
||||||
|
const EquipmentProfileDeleteEvent();
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:lightmeter/providers/equipment_profile_provider.dart';
|
||||||
|
import 'package:lightmeter/screens/equipment_profile_edit/bloc_equipment_profile_edit.dart';
|
||||||
|
import 'package:lightmeter/screens/equipment_profile_edit/screen_equipment_profile_edit.dart';
|
||||||
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
|
class EquipmentProfileEditArgs {
|
||||||
|
final EquipmentProfile? profile;
|
||||||
|
|
||||||
|
const EquipmentProfileEditArgs({this.profile});
|
||||||
|
}
|
||||||
|
|
||||||
|
class EquipmentProfileEditFlow extends StatelessWidget {
|
||||||
|
final EquipmentProfileEditArgs args;
|
||||||
|
|
||||||
|
const EquipmentProfileEditFlow({required this.args, super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (_) => EquipmentProfileEditBloc(
|
||||||
|
EquipmentProfileProvider.of(context),
|
||||||
|
profile: args.profile,
|
||||||
|
isEdit: args.profile != null,
|
||||||
|
),
|
||||||
|
child: EquipmentProfileEditScreen(isEdit: args.profile != null),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,233 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:lightmeter/generated/l10n.dart';
|
||||||
|
import 'package:lightmeter/res/dimens.dart';
|
||||||
|
import 'package:lightmeter/screens/equipment_profile_edit/bloc_equipment_profile_edit.dart';
|
||||||
|
import 'package:lightmeter/screens/equipment_profile_edit/components/filter_list_tile/widget_list_tile_filter.dart';
|
||||||
|
import 'package:lightmeter/screens/equipment_profile_edit/components/range_picker_list_tile/widget_list_tile_range_picker.dart';
|
||||||
|
import 'package:lightmeter/screens/equipment_profile_edit/components/slider_picker_list_tile/widget_list_tile_slider_picker.dart';
|
||||||
|
import 'package:lightmeter/screens/equipment_profile_edit/event_equipment_profile_edit.dart';
|
||||||
|
import 'package:lightmeter/screens/equipment_profile_edit/state_equipment_profile_edit.dart';
|
||||||
|
import 'package:lightmeter/screens/shared/sliver_screen/screen_sliver.dart';
|
||||||
|
import 'package:lightmeter/screens/shared/text_field/widget_text_field.dart';
|
||||||
|
import 'package:lightmeter/utils/double_to_zoom.dart';
|
||||||
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
|
class EquipmentProfileEditScreen extends StatefulWidget {
|
||||||
|
final bool isEdit;
|
||||||
|
|
||||||
|
const EquipmentProfileEditScreen({
|
||||||
|
required this.isEdit,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<EquipmentProfileEditScreen> createState() => _EquipmentProfileEditScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _EquipmentProfileEditScreenState extends State<EquipmentProfileEditScreen> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocConsumer<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
||||||
|
listenWhen: (previous, current) => previous.isLoading != current.isLoading,
|
||||||
|
listener: (context, state) {
|
||||||
|
if (state.isLoading) {
|
||||||
|
FocusScope.of(context).unfocus();
|
||||||
|
} else {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
buildWhen: (previous, current) => previous.isLoading != current.isLoading,
|
||||||
|
builder: (context, state) => IgnorePointer(
|
||||||
|
ignoring: state.isLoading,
|
||||||
|
child: SliverScreen(
|
||||||
|
title: Text(widget.isEdit ? S.of(context).editEquipmentProfileTitle : S.of(context).addEquipmentProfileTitle),
|
||||||
|
appBarActions: [
|
||||||
|
BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
||||||
|
buildWhen: (previous, current) => previous.canSave != current.canSave,
|
||||||
|
builder: (context, state) => IconButton(
|
||||||
|
onPressed: state.canSave
|
||||||
|
? () {
|
||||||
|
context.read<EquipmentProfileEditBloc>().add(const EquipmentProfileSaveEvent());
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
icon: const Icon(Icons.save),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (widget.isEdit)
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
context.read<EquipmentProfileEditBloc>().add(const EquipmentProfileDeleteEvent());
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.delete),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
slivers: [
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(
|
||||||
|
Dimens.paddingM,
|
||||||
|
0,
|
||||||
|
Dimens.paddingM,
|
||||||
|
Dimens.paddingM,
|
||||||
|
),
|
||||||
|
child: Card(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: Dimens.paddingM),
|
||||||
|
child: Opacity(
|
||||||
|
opacity: state.isLoading ? Dimens.disabledOpacity : Dimens.enabledOpacity,
|
||||||
|
child: const Column(
|
||||||
|
children: [
|
||||||
|
_NameFieldBuilder(),
|
||||||
|
_IsoValuesListTileBuilder(),
|
||||||
|
_NdValuesListTileBuilder(),
|
||||||
|
_ApertureValuesListTileBuilder(),
|
||||||
|
_ShutterSpeedValuesListTileBuilder(),
|
||||||
|
_LensZoomListTileBuilder(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SliverToBoxAdapter(child: SizedBox(height: MediaQuery.paddingOf(context).bottom)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NameFieldBuilder extends StatelessWidget {
|
||||||
|
const _NameFieldBuilder();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
||||||
|
builder: (context, state) => Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: Dimens.paddingM,
|
||||||
|
top: Dimens.paddingS / 2,
|
||||||
|
right: Dimens.paddingL,
|
||||||
|
bottom: Dimens.paddingS / 2,
|
||||||
|
),
|
||||||
|
child: LightmeterTextField(
|
||||||
|
initialValue: state.name,
|
||||||
|
autofocus: true,
|
||||||
|
maxLength: 48,
|
||||||
|
hintText: S.of(context).name,
|
||||||
|
style: Theme.of(context).listTileTheme.titleTextStyle,
|
||||||
|
leading: const Icon(Icons.edit_outlined),
|
||||||
|
onChanged: (value) {
|
||||||
|
context.read<EquipmentProfileEditBloc>().add(EquipmentProfileNameChangedEvent(value));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _IsoValuesListTileBuilder extends StatelessWidget {
|
||||||
|
const _IsoValuesListTileBuilder();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
||||||
|
builder: (context, state) => FilterListTile<IsoValue>(
|
||||||
|
icon: Icons.iso_outlined,
|
||||||
|
title: S.of(context).isoValues,
|
||||||
|
description: S.of(context).isoValuesFilterDescription,
|
||||||
|
values: IsoValue.values,
|
||||||
|
selectedValues: state.isoValues,
|
||||||
|
onChanged: (value) {
|
||||||
|
context.read<EquipmentProfileEditBloc>().add(EquipmentProfileIsoValuesChangedEvent(value));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NdValuesListTileBuilder extends StatelessWidget {
|
||||||
|
const _NdValuesListTileBuilder();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
||||||
|
builder: (context, state) => FilterListTile<NdValue>(
|
||||||
|
icon: Icons.filter_b_and_w_outlined,
|
||||||
|
title: S.of(context).ndFilters,
|
||||||
|
description: S.of(context).ndFiltersFilterDescription,
|
||||||
|
values: NdValue.values,
|
||||||
|
selectedValues: state.ndValues,
|
||||||
|
onChanged: (value) {
|
||||||
|
context.read<EquipmentProfileEditBloc>().add(EquipmentProfileNdValuesChangedEvent(value));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ApertureValuesListTileBuilder extends StatelessWidget {
|
||||||
|
const _ApertureValuesListTileBuilder();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
||||||
|
builder: (context, state) => RangePickerListTile<ApertureValue>(
|
||||||
|
icon: Icons.camera_outlined,
|
||||||
|
title: S.of(context).apertureValues,
|
||||||
|
description: S.of(context).apertureValuesFilterDescription,
|
||||||
|
values: ApertureValue.values,
|
||||||
|
selectedValues: state.apertureValues,
|
||||||
|
onChanged: (value) {
|
||||||
|
context.read<EquipmentProfileEditBloc>().add(EquipmentProfileApertureValuesChangedEvent(value));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ShutterSpeedValuesListTileBuilder extends StatelessWidget {
|
||||||
|
const _ShutterSpeedValuesListTileBuilder();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
||||||
|
builder: (context, state) => RangePickerListTile<ShutterSpeedValue>(
|
||||||
|
icon: Icons.shutter_speed_outlined,
|
||||||
|
title: S.of(context).shutterSpeedValues,
|
||||||
|
description: S.of(context).shutterSpeedValuesFilterDescription,
|
||||||
|
values: ShutterSpeedValue.values,
|
||||||
|
selectedValues: state.shutterSpeedValues,
|
||||||
|
trailingAdapter: (context, value) =>
|
||||||
|
value.value == 1 ? S.of(context).shutterSpeedManualShort : value.toString(),
|
||||||
|
dialogValueAdapter: (context, value) => value.value == 1 ? S.of(context).shutterSpeedManual : value.toString(),
|
||||||
|
onChanged: (value) {
|
||||||
|
context.read<EquipmentProfileEditBloc>().add(EquipmentProfileShutterSpeedValuesChangedEvent(value));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LensZoomListTileBuilder extends StatelessWidget {
|
||||||
|
const _LensZoomListTileBuilder();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<EquipmentProfileEditBloc, EquipmentProfileEditState>(
|
||||||
|
builder: (context, state) => SliderPickerListTile(
|
||||||
|
icon: Icons.zoom_in_outlined,
|
||||||
|
title: S.of(context).lensZoom,
|
||||||
|
description: S.of(context).lensZoomDescription,
|
||||||
|
value: state.lensZoom,
|
||||||
|
range: const RangeValues(1, 7),
|
||||||
|
valueAdapter: (_, value) => value.toZoom(),
|
||||||
|
onChanged: (value) {
|
||||||
|
context.read<EquipmentProfileEditBloc>().add(EquipmentProfileLensZoomChangedEvent(value));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
|
class EquipmentProfileEditState {
|
||||||
|
final String name;
|
||||||
|
final List<ApertureValue> apertureValues;
|
||||||
|
final List<NdValue> ndValues;
|
||||||
|
final List<ShutterSpeedValue> shutterSpeedValues;
|
||||||
|
final List<IsoValue> isoValues;
|
||||||
|
final double lensZoom;
|
||||||
|
final bool canSave;
|
||||||
|
final bool isLoading;
|
||||||
|
|
||||||
|
const EquipmentProfileEditState({
|
||||||
|
required this.name,
|
||||||
|
required this.apertureValues,
|
||||||
|
required this.ndValues,
|
||||||
|
required this.shutterSpeedValues,
|
||||||
|
required this.isoValues,
|
||||||
|
required this.lensZoom,
|
||||||
|
required this.canSave,
|
||||||
|
this.isLoading = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
EquipmentProfileEditState copyWith({
|
||||||
|
String? name,
|
||||||
|
List<ApertureValue>? apertureValues,
|
||||||
|
List<NdValue>? ndValues,
|
||||||
|
List<ShutterSpeedValue>? shutterSpeedValues,
|
||||||
|
List<IsoValue>? isoValues,
|
||||||
|
double? lensZoom,
|
||||||
|
bool? canSave,
|
||||||
|
bool? isLoading,
|
||||||
|
}) =>
|
||||||
|
EquipmentProfileEditState(
|
||||||
|
name: name ?? this.name,
|
||||||
|
apertureValues: apertureValues ?? this.apertureValues,
|
||||||
|
ndValues: ndValues ?? this.ndValues,
|
||||||
|
shutterSpeedValues: shutterSpeedValues ?? this.shutterSpeedValues,
|
||||||
|
isoValues: isoValues ?? this.isoValues,
|
||||||
|
lensZoom: lensZoom ?? this.lensZoom,
|
||||||
|
canSave: canSave ?? this.canSave,
|
||||||
|
isLoading: isLoading ?? this.isLoading,
|
||||||
|
);
|
||||||
|
}
|
|
@ -4,11 +4,6 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:lightmeter/generated/l10n.dart';
|
import 'package:lightmeter/generated/l10n.dart';
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
import 'package:lightmeter/res/dimens.dart';
|
||||||
import 'package:lightmeter/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/components/equipment_profile_container/components/filter_list_tile/widget_list_tile_filter.dart';
|
|
||||||
import 'package:lightmeter/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/components/equipment_profile_container/components/range_picker_list_tile/widget_list_tile_range_picker.dart';
|
|
||||||
import 'package:lightmeter/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/components/equipment_profile_container/components/slider_picker_list_tile/widget_list_tile_slider_picker.dart';
|
|
||||||
import 'package:lightmeter/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/components/equipment_profile_name_dialog/widget_dialog_equipment_profile_name.dart';
|
|
||||||
import 'package:lightmeter/utils/double_to_zoom.dart';
|
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
class EquipmentProfileContainer extends StatefulWidget {
|
class EquipmentProfileContainer extends StatefulWidget {
|
||||||
|
@ -130,17 +125,7 @@ class EquipmentProfileContainerState extends State<EquipmentProfileContainer> wi
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showNameDialog() {
|
void _showNameDialog() {}
|
||||||
showDialog<String>(
|
|
||||||
context: context,
|
|
||||||
builder: (_) => EquipmentProfileNameDialog(initialValue: _equipmentData.name),
|
|
||||||
).then((value) {
|
|
||||||
if (value != null) {
|
|
||||||
_equipmentData = _equipmentData.copyWith(name: value);
|
|
||||||
widget.onUpdate(_equipmentData);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void expand() {
|
void expand() {
|
||||||
widget.onExpand();
|
widget.onExpand();
|
||||||
|
@ -238,51 +223,6 @@ class _AnimatedEquipmentListTiles extends AnimatedWidget {
|
||||||
opacity: _progress.value,
|
opacity: _progress.value,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
FilterListTile<IsoValue>(
|
|
||||||
icon: Icons.iso_outlined,
|
|
||||||
title: S.of(context).isoValues,
|
|
||||||
description: S.of(context).isoValuesFilterDescription,
|
|
||||||
values: IsoValue.values,
|
|
||||||
selectedValues: equipmentData.isoValues,
|
|
||||||
onChanged: onIsoValuesSelecred,
|
|
||||||
),
|
|
||||||
FilterListTile<NdValue>(
|
|
||||||
icon: Icons.filter_b_and_w_outlined,
|
|
||||||
title: S.of(context).ndFilters,
|
|
||||||
description: S.of(context).ndFiltersFilterDescription,
|
|
||||||
values: NdValue.values,
|
|
||||||
selectedValues: equipmentData.ndValues,
|
|
||||||
onChanged: onNdValuesSelected,
|
|
||||||
),
|
|
||||||
RangePickerListTile<ApertureValue>(
|
|
||||||
icon: Icons.camera_outlined,
|
|
||||||
title: S.of(context).apertureValues,
|
|
||||||
description: S.of(context).apertureValuesFilterDescription,
|
|
||||||
values: ApertureValue.values,
|
|
||||||
selectedValues: equipmentData.apertureValues,
|
|
||||||
onChanged: onApertureValuesSelected,
|
|
||||||
),
|
|
||||||
RangePickerListTile<ShutterSpeedValue>(
|
|
||||||
icon: Icons.shutter_speed_outlined,
|
|
||||||
title: S.of(context).shutterSpeedValues,
|
|
||||||
description: S.of(context).shutterSpeedValuesFilterDescription,
|
|
||||||
values: ShutterSpeedValue.values,
|
|
||||||
selectedValues: equipmentData.shutterSpeedValues,
|
|
||||||
onChanged: onShutterSpeedValuesSelected,
|
|
||||||
trailingAdapter: (context, value) =>
|
|
||||||
value.value == 1 ? S.of(context).shutterSpeedManualShort : value.toString(),
|
|
||||||
dialogValueAdapter: (context, value) =>
|
|
||||||
value.value == 1 ? S.of(context).shutterSpeedManual : value.toString(),
|
|
||||||
),
|
|
||||||
SliderPickerListTile(
|
|
||||||
icon: Icons.zoom_in_outlined,
|
|
||||||
title: S.of(context).lensZoom,
|
|
||||||
description: S.of(context).lensZoomDescription,
|
|
||||||
value: equipmentData.lensZoom,
|
|
||||||
range: const RangeValues(1, 7),
|
|
||||||
onChanged: onLensZoomChanged,
|
|
||||||
valueAdapter: (_, value) => value.toZoom(),
|
|
||||||
),
|
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: Dimens.paddingM),
|
contentPadding: const EdgeInsets.symmetric(horizontal: Dimens.paddingM),
|
||||||
trailing: Row(
|
trailing: Row(
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:lightmeter/generated/l10n.dart';
|
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
|
||||||
|
|
||||||
class EquipmentProfileNameDialog extends StatefulWidget {
|
|
||||||
final String initialValue;
|
|
||||||
|
|
||||||
const EquipmentProfileNameDialog({this.initialValue = '', super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<EquipmentProfileNameDialog> createState() => _EquipmentProfileNameDialogState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _EquipmentProfileNameDialogState extends State<EquipmentProfileNameDialog> {
|
|
||||||
late final _nameController = TextEditingController(text: widget.initialValue);
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_nameController.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return AlertDialog(
|
|
||||||
icon: const Icon(Icons.edit_outlined),
|
|
||||||
titlePadding: Dimens.dialogIconTitlePadding,
|
|
||||||
title: Text(S.of(context).equipmentProfileName),
|
|
||||||
content: TextField(
|
|
||||||
autofocus: true,
|
|
||||||
controller: _nameController,
|
|
||||||
decoration: InputDecoration(hintText: S.of(context).equipmentProfileNameHint),
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: Navigator.of(context).pop,
|
|
||||||
child: Text(S.of(context).cancel),
|
|
||||||
),
|
|
||||||
ValueListenableBuilder(
|
|
||||||
valueListenable: _nameController,
|
|
||||||
builder: (_, value, __) => TextButton(
|
|
||||||
onPressed: value.text.isNotEmpty ? () => Navigator.of(context).pop(value.text) : null,
|
|
||||||
child: Text(S.of(context).save),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,7 +3,6 @@ import 'package:lightmeter/generated/l10n.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/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/components/equipment_profile_container/widget_container_equipment_profile.dart';
|
import 'package:lightmeter/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/components/equipment_profile_container/widget_container_equipment_profile.dart';
|
||||||
import 'package:lightmeter/screens/settings/components/metering/components/equipment_profiles/components/equipment_profile_screen/components/equipment_profile_name_dialog/widget_dialog_equipment_profile_name.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:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
@ -73,24 +72,11 @@ class _EquipmentProfilesScreenState extends State<EquipmentProfilesScreen> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _addProfile([EquipmentProfile? copyFrom]) {
|
void _addProfile([EquipmentProfile? copyFrom]) {}
|
||||||
showDialog<String>(
|
|
||||||
context: context,
|
|
||||||
builder: (_) => const EquipmentProfileNameDialog(),
|
|
||||||
).then((name) {
|
|
||||||
if (name != null) {
|
|
||||||
//EquipmentProfileProvider.of(context).addProfile(name, copyFrom);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void _updateProfileAt(EquipmentProfile data) {
|
void _updateProfileAt(EquipmentProfile data) {}
|
||||||
EquipmentProfileProvider.of(context).updateProfile(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _removeProfileAt(EquipmentProfile data) {
|
void _removeProfileAt(EquipmentProfile data) {}
|
||||||
EquipmentProfileProvider.of(context).deleteProfile(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _keepExpandedAt(int index) {
|
void _keepExpandedAt(int index) {
|
||||||
keysMap.values.toList().getRange(0, index).forEach((element) {
|
keysMap.values.toList().getRange(0, index).forEach((element) {
|
||||||
|
|
Loading…
Reference in a new issue