mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-22 15:30:59 +00:00
improved equipment profiles screen
This commit is contained in:
parent
82c63803bb
commit
5e814184f0
7 changed files with 176 additions and 129 deletions
|
@ -8,7 +8,6 @@ import 'package:lightmeter/data/caffeine_service.dart';
|
||||||
import 'package:lightmeter/data/haptics_service.dart';
|
import 'package:lightmeter/data/haptics_service.dart';
|
||||||
import 'package:lightmeter/data/models/supported_locale.dart';
|
import 'package:lightmeter/data/models/supported_locale.dart';
|
||||||
import 'package:lightmeter/providers/supported_locale_provider.dart';
|
import 'package:lightmeter/providers/supported_locale_provider.dart';
|
||||||
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
@ -48,33 +47,31 @@ class Application extends StatelessWidget {
|
||||||
Provider(create: (_) => PermissionsService()),
|
Provider(create: (_) => PermissionsService()),
|
||||||
Provider(create: (_) => const LightSensorService()),
|
Provider(create: (_) => const LightSensorService()),
|
||||||
],
|
],
|
||||||
child: IAPProductsProvider(
|
child: StopTypeProvider(
|
||||||
child: StopTypeProvider(
|
child: EquipmentProfileProvider(
|
||||||
child: EquipmentProfileProvider(
|
child: EvSourceTypeProvider(
|
||||||
child: EvSourceTypeProvider(
|
child: SupportedLocaleProvider(
|
||||||
child: SupportedLocaleProvider(
|
child: ThemeProvider(
|
||||||
child: ThemeProvider(
|
builder: (context, _) => _AnnotatedRegionWrapper(
|
||||||
builder: (context, _) => _AnnotatedRegionWrapper(
|
child: MaterialApp(
|
||||||
child: MaterialApp(
|
theme: context.watch<ThemeData>(),
|
||||||
theme: context.watch<ThemeData>(),
|
locale: Locale(context.watch<SupportedLocale>().intlName),
|
||||||
locale: Locale(context.watch<SupportedLocale>().intlName),
|
localizationsDelegates: const [
|
||||||
localizationsDelegates: const [
|
S.delegate,
|
||||||
S.delegate,
|
GlobalMaterialLocalizations.delegate,
|
||||||
GlobalMaterialLocalizations.delegate,
|
GlobalWidgetsLocalizations.delegate,
|
||||||
GlobalWidgetsLocalizations.delegate,
|
GlobalCupertinoLocalizations.delegate,
|
||||||
GlobalCupertinoLocalizations.delegate,
|
],
|
||||||
],
|
supportedLocales: S.delegate.supportedLocales,
|
||||||
supportedLocales: S.delegate.supportedLocales,
|
builder: (context, child) => MediaQuery(
|
||||||
builder: (context, child) => MediaQuery(
|
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
|
||||||
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
|
child: child!,
|
||||||
child: child!,
|
|
||||||
),
|
|
||||||
initialRoute: "metering",
|
|
||||||
routes: {
|
|
||||||
"metering": (context) => const MeteringFlow(),
|
|
||||||
"settings": (context) => const SettingsFlow(),
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
|
initialRoute: "metering",
|
||||||
|
routes: {
|
||||||
|
"metering": (context) => const MeteringFlow(),
|
||||||
|
"settings": (context) => const SettingsFlow(),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -38,8 +38,7 @@ class ReadingsContainer extends StatelessWidget {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
if (IAPProducts.of(context, IAPProductType.equipment)?.status ==
|
if (true) ...[
|
||||||
IAPProductStatus.purchased) ...[
|
|
||||||
ReadingValueContainer.singleValue(
|
ReadingValueContainer.singleValue(
|
||||||
value: ReadingValue(
|
value: ReadingValue(
|
||||||
label: S.of(context).equipment,
|
label: S.of(context).equipment,
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
|
||||||
|
|
||||||
import '../dialog_filter/widget_dialog_filter.dart';
|
|
||||||
|
|
||||||
class EquipmentListTile<T extends PhotographyValue> extends StatelessWidget {
|
|
||||||
final IconData icon;
|
|
||||||
final String title;
|
|
||||||
final String description;
|
|
||||||
final List<T> selectedValues;
|
|
||||||
final List<T> values;
|
|
||||||
final ValueChanged<List<T>> onChanged;
|
|
||||||
final bool rangeSelect;
|
|
||||||
|
|
||||||
const EquipmentListTile({
|
|
||||||
required this.icon,
|
|
||||||
required this.title,
|
|
||||||
required this.description,
|
|
||||||
required this.selectedValues,
|
|
||||||
required this.values,
|
|
||||||
required this.onChanged,
|
|
||||||
required this.rangeSelect,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return ListTile(
|
|
||||||
leading: Icon(icon),
|
|
||||||
title: Text(title),
|
|
||||||
onTap: () {
|
|
||||||
showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (_) => DialogFilter<T>(
|
|
||||||
icon: Icon(icon),
|
|
||||||
title: title,
|
|
||||||
description: description,
|
|
||||||
values: values,
|
|
||||||
titleAdapter: (_, value) => value.toString(),
|
|
||||||
rangeSelect: rangeSelect,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:lightmeter/generated/l10n.dart';
|
||||||
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
import 'package:lightmeter/screens/settings/components/shared/dialog_filter/widget_dialog_filter.dart';
|
||||||
|
|
||||||
|
class EquipmentListTiles extends StatelessWidget {
|
||||||
|
final List<ApertureValue> selectedApertureValues;
|
||||||
|
final List<IsoValue> selectedIsoValues;
|
||||||
|
final List<NdValue> selectedNdValues;
|
||||||
|
final List<ShutterSpeedValue> selectedShutterSpeedValues;
|
||||||
|
final ValueChanged<List<ApertureValue>> onApertureValuesSelected;
|
||||||
|
final ValueChanged<List<IsoValue>> onIsoValuesSelecred;
|
||||||
|
final ValueChanged<List<NdValue>> onNdValuesSelected;
|
||||||
|
final ValueChanged<List<ShutterSpeedValue>> onShutterSpeedValuesSelected;
|
||||||
|
|
||||||
|
const EquipmentListTiles({
|
||||||
|
required this.selectedApertureValues,
|
||||||
|
required this.selectedIsoValues,
|
||||||
|
required this.selectedNdValues,
|
||||||
|
required this.selectedShutterSpeedValues,
|
||||||
|
required this.onApertureValuesSelected,
|
||||||
|
required this.onIsoValuesSelecred,
|
||||||
|
required this.onNdValuesSelected,
|
||||||
|
required this.onShutterSpeedValuesSelected,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
_EquipmentListTile<IsoValue>(
|
||||||
|
icon: Icons.iso,
|
||||||
|
title: S.of(context).isoValues,
|
||||||
|
description: S.of(context).isoValuesFilterDescription,
|
||||||
|
values: isoValues,
|
||||||
|
selectedValues: selectedIsoValues,
|
||||||
|
rangeSelect: false,
|
||||||
|
onChanged: onIsoValuesSelecred,
|
||||||
|
),
|
||||||
|
_EquipmentListTile<NdValue>(
|
||||||
|
icon: Icons.filter_b_and_w,
|
||||||
|
title: S.of(context).ndFilters,
|
||||||
|
description: S.of(context).ndFiltersFilterDescription,
|
||||||
|
values: ndValues,
|
||||||
|
selectedValues: selectedNdValues,
|
||||||
|
rangeSelect: false,
|
||||||
|
onChanged: onNdValuesSelected,
|
||||||
|
),
|
||||||
|
_EquipmentListTile<ApertureValue>(
|
||||||
|
icon: Icons.camera,
|
||||||
|
title: S.of(context).apertureValues,
|
||||||
|
description: S.of(context).apertureValuesFilterDescription,
|
||||||
|
values: apertureValues,
|
||||||
|
selectedValues: selectedApertureValues,
|
||||||
|
rangeSelect: true,
|
||||||
|
onChanged: onApertureValuesSelected,
|
||||||
|
),
|
||||||
|
_EquipmentListTile<ShutterSpeedValue>(
|
||||||
|
icon: Icons.shutter_speed,
|
||||||
|
title: S.of(context).shutterSpeedValues,
|
||||||
|
description: S.of(context).shutterSpeedValuesFilterDescription,
|
||||||
|
values: shutterSpeedValues,
|
||||||
|
selectedValues: selectedShutterSpeedValues,
|
||||||
|
rangeSelect: true,
|
||||||
|
onChanged: onShutterSpeedValuesSelected,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _EquipmentListTile<T extends PhotographyValue> extends StatelessWidget {
|
||||||
|
final IconData icon;
|
||||||
|
final String title;
|
||||||
|
final String description;
|
||||||
|
final List<T> selectedValues;
|
||||||
|
final List<T> values;
|
||||||
|
final ValueChanged<List<T>> onChanged;
|
||||||
|
final bool rangeSelect;
|
||||||
|
|
||||||
|
const _EquipmentListTile({
|
||||||
|
required this.icon,
|
||||||
|
required this.title,
|
||||||
|
required this.description,
|
||||||
|
required this.selectedValues,
|
||||||
|
required this.values,
|
||||||
|
required this.onChanged,
|
||||||
|
required this.rangeSelect,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ListTile(
|
||||||
|
leading: Icon(icon),
|
||||||
|
title: Text(title),
|
||||||
|
onTap: () {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (_) => DialogFilter<T>(
|
||||||
|
icon: Icon(icon),
|
||||||
|
title: title,
|
||||||
|
description: description,
|
||||||
|
values: values,
|
||||||
|
titleAdapter: (_, value) => value.toString(),
|
||||||
|
rangeSelect: rangeSelect,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:lightmeter/generated/l10n.dart';
|
import 'package:lightmeter/generated/l10n.dart';
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
import 'components/equipment_list_tile/widget_list_tile_equipment.dart';
|
import 'components/equipment_list_tiles/widget_list_tiles_equipments.dart';
|
||||||
|
|
||||||
class EquipmentListTilesSection extends StatefulWidget {
|
class EquipmentListTilesSection extends StatefulWidget {
|
||||||
final EquipmentProfileData data;
|
final EquipmentProfileData data;
|
||||||
|
@ -69,7 +70,17 @@ class _EquipmentListTilesSectionState extends State<EquipmentListTilesSection> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (_expanded) const _DialogsListTiles()
|
if (_expanded)
|
||||||
|
EquipmentListTiles(
|
||||||
|
selectedApertureValues: widget.data.apertureValues,
|
||||||
|
selectedIsoValues: widget.data.isoValues,
|
||||||
|
selectedNdValues: widget.data.ndValues,
|
||||||
|
selectedShutterSpeedValues: widget.data.shutterSpeedValues,
|
||||||
|
onApertureValuesSelected: (value) {},
|
||||||
|
onIsoValuesSelecred: (value) {},
|
||||||
|
onNdValuesSelected: (value) {},
|
||||||
|
onShutterSpeedValuesSelected: (value) {},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -82,7 +93,14 @@ class _EquipmentListTilesSectionState extends State<EquipmentListTilesSection> {
|
||||||
setState(() {
|
setState(() {
|
||||||
_expanded = !_expanded;
|
_expanded = !_expanded;
|
||||||
});
|
});
|
||||||
if (!_expanded) {
|
if (_expanded) {
|
||||||
|
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||||
|
Scrollable.ensureVisible(
|
||||||
|
context,
|
||||||
|
alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtEnd,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
_fieldFocusNode.unfocus();
|
_fieldFocusNode.unfocus();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -90,52 +108,3 @@ class _EquipmentListTilesSectionState extends State<EquipmentListTilesSection> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DialogsListTiles extends StatelessWidget {
|
|
||||||
const _DialogsListTiles();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
EquipmentListTile<IsoValue>(
|
|
||||||
icon: Icons.iso,
|
|
||||||
title: S.of(context).isoValues,
|
|
||||||
description: S.of(context).isoValuesFilterDescription,
|
|
||||||
values: isoValues,
|
|
||||||
selectedValues: const [],
|
|
||||||
rangeSelect: false,
|
|
||||||
onChanged: (value) {},
|
|
||||||
),
|
|
||||||
EquipmentListTile<NdValue>(
|
|
||||||
icon: Icons.filter_b_and_w,
|
|
||||||
title: S.of(context).ndFilters,
|
|
||||||
description: S.of(context).ndFiltersFilterDescription,
|
|
||||||
values: ndValues,
|
|
||||||
selectedValues: const [],
|
|
||||||
rangeSelect: false,
|
|
||||||
onChanged: (value) {},
|
|
||||||
),
|
|
||||||
EquipmentListTile<ApertureValue>(
|
|
||||||
icon: Icons.camera,
|
|
||||||
title: S.of(context).apertureValues,
|
|
||||||
description: S.of(context).apertureValuesFilterDescription,
|
|
||||||
values: apertureValues,
|
|
||||||
selectedValues: const [],
|
|
||||||
rangeSelect: true,
|
|
||||||
onChanged: (value) {},
|
|
||||||
),
|
|
||||||
EquipmentListTile<ShutterSpeedValue>(
|
|
||||||
icon: Icons.shutter_speed,
|
|
||||||
title: S.of(context).shutterSpeedValues,
|
|
||||||
description: S.of(context).shutterSpeedValuesFilterDescription,
|
|
||||||
values: shutterSpeedValues,
|
|
||||||
selectedValues: const [],
|
|
||||||
rangeSelect: true,
|
|
||||||
onChanged: (value) {},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -23,14 +23,28 @@ class _EquipmentProfileScreenState extends State<EquipmentProfileScreen> {
|
||||||
),
|
),
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
bottom: false,
|
bottom: false,
|
||||||
child: ListView.builder(
|
child: ListView.separated(
|
||||||
padding: const EdgeInsets.all(Dimens.paddingM),
|
padding: EdgeInsets.fromLTRB(
|
||||||
|
Dimens.paddingM,
|
||||||
|
Dimens.paddingM,
|
||||||
|
Dimens.paddingM,
|
||||||
|
Dimens.paddingM +
|
||||||
|
MediaQuery.of(context).padding.bottom +
|
||||||
|
Dimens.grid56 +
|
||||||
|
kFloatingActionButtonMargin,
|
||||||
|
),
|
||||||
|
separatorBuilder: (context, index) => const SizedBox(height: Dimens.grid16),
|
||||||
itemCount: EquipmentProfiles.of(context)?.length ?? 0,
|
itemCount: EquipmentProfiles.of(context)?.length ?? 0,
|
||||||
itemBuilder: (_, index) => EquipmentListTilesSection(
|
itemBuilder: (_, index) => EquipmentListTilesSection(
|
||||||
data: EquipmentProfiles.of(context)![index],
|
data: EquipmentProfiles.of(context)![index],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
onPressed: EquipmentProfileProvider.of(context).addProfile,
|
||||||
|
child: const Icon(Icons.add),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue