ML-170 Show long shutter speeds for all selected aperture values (#172)

* generate exposures > 1"

* fixed unit tests

* added manual shutter speed to equipment profiles

* fixed integration tests

* fixed unit tests

* fixed long exposures overflow

* migrated to resources 1.2.0 and iap 0.10.0

* removed unnecessary loop

* fixed extreme exposure pairs test

* updated master screenshots

* fixed iap stub
This commit is contained in:
Vadim 2024-04-30 12:44:01 +02:00 committed by GitHub
parent ec1f1eeeb4
commit bc7e6e14d0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 345 additions and 869 deletions

View file

@ -13,7 +13,7 @@ dependencies:
m3_lightmeter_resources: m3_lightmeter_resources:
git: git:
url: "https://github.com/vodemn/m3_lightmeter_resources" url: "https://github.com/vodemn/m3_lightmeter_resources"
ref: main ref: v1.2.0
shared_preferences: 2.2.0 shared_preferences: 2.2.0
dev_dependencies: dev_dependencies:

View file

@ -44,7 +44,7 @@ void testE2E(String description) {
testWidgets( testWidgets(
description, description,
(tester) async { (tester) async {
await tester.pumpApplication(equipmentProfiles: [], films: []); await tester.pumpApplication(equipmentProfiles: [], filmsInUse: []);
/// Create Praktica + Zenitar profile from scratch /// Create Praktica + Zenitar profile from scratch
await tester.openSettings(); await tester.openSettings();
@ -60,7 +60,7 @@ void testE2E(String description) {
await tester.setZoomValue(0, mockEquipmentProfiles[0].lensZoom); await tester.setZoomValue(0, mockEquipmentProfiles[0].lensZoom);
expect(find.text('x1.91'), findsOneWidget); expect(find.text('x1.91'), findsOneWidget);
expect(find.text('f/1.7 - f/16'), findsOneWidget); expect(find.text('f/1.7 - f/16'), findsOneWidget);
expect(find.text('1/1000 - 16"'), findsOneWidget); expect(find.text('1/1000 - B'), findsOneWidget);
/// Create Praktica + Jupiter profile from Zenitar profile /// Create Praktica + Jupiter profile from Zenitar profile
await tester.tap(find.byIcon(Icons.copy).first); await tester.tap(find.byIcon(Icons.copy).first);
@ -71,7 +71,7 @@ void testE2E(String description) {
await tester.setZoomValue(1, mockEquipmentProfiles[1].lensZoom); await tester.setZoomValue(1, mockEquipmentProfiles[1].lensZoom);
expect(find.text('x5.02'), findsOneWidget); expect(find.text('x5.02'), findsOneWidget);
expect(find.text('f/3.5 - f/22'), findsOneWidget); expect(find.text('f/3.5 - f/22'), findsOneWidget);
expect(find.text('1/1000 - 16"'), findsNWidgets(2)); expect(find.text('1/1000 - B'), findsNWidgets(2));
await tester.navigatorPop(); await tester.navigatorPop();
/// Select some films /// Select some films

View file

@ -10,18 +10,21 @@ class _MockIAPStorageService extends Mock implements IAPStorageService {}
class MockIAPProviders extends StatefulWidget { class MockIAPProviders extends StatefulWidget {
final List<EquipmentProfile>? equipmentProfiles; final List<EquipmentProfile>? equipmentProfiles;
final String selectedEquipmentProfileId; final String selectedEquipmentProfileId;
final List<Film>? films; final List<Film> availableFilms;
final List<Film> filmsInUse;
final Film selectedFilm; final Film selectedFilm;
final Widget child; final Widget child;
const MockIAPProviders({ const MockIAPProviders({
this.equipmentProfiles = const [], this.equipmentProfiles = const [],
this.selectedEquipmentProfileId = '', this.selectedEquipmentProfileId = '',
this.films = mockFilms, List<Film>? availableFilms,
List<Film>? filmsInUse,
this.selectedFilm = const Film.other(), this.selectedFilm = const Film.other(),
required this.child, required this.child,
super.key, super.key,
}); }) : availableFilms = availableFilms ?? mockFilms,
filmsInUse = filmsInUse ?? mockFilms;
@override @override
State<MockIAPProviders> createState() => _MockIAPProvidersState(); State<MockIAPProviders> createState() => _MockIAPProvidersState();
@ -36,7 +39,7 @@ class _MockIAPProvidersState extends State<MockIAPProviders> {
mockIAPStorageService = _MockIAPStorageService(); mockIAPStorageService = _MockIAPStorageService();
when(() => mockIAPStorageService.equipmentProfiles).thenReturn(widget.equipmentProfiles ?? mockEquipmentProfiles); when(() => mockIAPStorageService.equipmentProfiles).thenReturn(widget.equipmentProfiles ?? mockEquipmentProfiles);
when(() => mockIAPStorageService.selectedEquipmentProfileId).thenReturn(widget.selectedEquipmentProfileId); when(() => mockIAPStorageService.selectedEquipmentProfileId).thenReturn(widget.selectedEquipmentProfileId);
when(() => mockIAPStorageService.filmsInUse).thenReturn(widget.films ?? mockFilms); when(() => mockIAPStorageService.filmsInUse).thenReturn(widget.filmsInUse);
when(() => mockIAPStorageService.selectedFilm).thenReturn(widget.selectedFilm); when(() => mockIAPStorageService.selectedFilm).thenReturn(widget.selectedFilm);
} }
@ -46,7 +49,7 @@ class _MockIAPProvidersState extends State<MockIAPProviders> {
storageService: mockIAPStorageService, storageService: mockIAPStorageService,
child: FilmsProvider( child: FilmsProvider(
storageService: mockIAPStorageService, storageService: mockIAPStorageService,
availableFilms: widget.films ?? mockFilms, availableFilms: widget.availableFilms,
child: widget.child, child: widget.child,
), ),
); );
@ -78,7 +81,7 @@ final mockEquipmentProfiles = [
], ],
shutterSpeedValues: ShutterSpeedValue.values.sublist( shutterSpeedValues: ShutterSpeedValue.values.sublist(
ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(1000, true, StopType.full)), ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(1000, true, StopType.full)),
ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(16, false, StopType.full)) + 1, ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(1, false, StopType.full)) + 1,
), ),
isoValues: const [ isoValues: const [
IsoValue(50, StopType.full), IsoValue(50, StopType.full),
@ -108,7 +111,7 @@ final mockEquipmentProfiles = [
], ],
shutterSpeedValues: ShutterSpeedValue.values.sublist( shutterSpeedValues: ShutterSpeedValue.values.sublist(
ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(1000, true, StopType.full)), ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(1000, true, StopType.full)),
ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(16, false, StopType.full)) + 1, ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(1, false, StopType.full)) + 1,
), ),
isoValues: const [ isoValues: const [
IsoValue(50, StopType.full), IsoValue(50, StopType.full),

View file

@ -22,7 +22,8 @@ extension WidgetTesterCommonActions on WidgetTester {
IAPProductStatus productStatus = IAPProductStatus.purchased, IAPProductStatus productStatus = IAPProductStatus.purchased,
List<EquipmentProfile>? equipmentProfiles, List<EquipmentProfile>? equipmentProfiles,
String selectedEquipmentProfileId = '', String selectedEquipmentProfileId = '',
List<Film>? films, List<Film>? availableFilms,
List<Film>? filmsInUse,
Film selectedFilm = const Film.other(), Film selectedFilm = const Film.other(),
}) async { }) async {
await pumpWidget( await pumpWidget(
@ -33,7 +34,8 @@ extension WidgetTesterCommonActions on WidgetTester {
child: MockIAPProviders( child: MockIAPProviders(
equipmentProfiles: equipmentProfiles, equipmentProfiles: equipmentProfiles,
selectedEquipmentProfileId: selectedEquipmentProfileId, selectedEquipmentProfileId: selectedEquipmentProfileId,
films: films, availableFilms: availableFilms,
filmsInUse: filmsInUse,
selectedFilm: selectedFilm, selectedFilm: selectedFilm,
child: const Application(), child: const Application(),
), ),

View file

@ -58,6 +58,8 @@
"ndFiltersFilterDescription": "Select the ND filters to display. These may be your most commonly used ND filters or the ones that fit your lens.", "ndFiltersFilterDescription": "Select the ND filters to display. These may be your most commonly used ND filters or the ones that fit your lens.",
"shutterSpeedValues": "Shutter speed values", "shutterSpeedValues": "Shutter speed values",
"shutterSpeedValuesFilterDescription": "Select the range of shutter speed values to display. This is usually determined by the camera body you are using.", "shutterSpeedValuesFilterDescription": "Select the range of shutter speed values to display. This is usually determined by the camera body you are using.",
"shutterSpeedManualShort": "B",
"shutterSpeedManual": "Manual",
"isoValues": "ISO values", "isoValues": "ISO values",
"isoValuesFilterDescription": "Select the ISO values to display. These may be your most commonly used values or those supported by your camera.", "isoValuesFilterDescription": "Select the ISO values to display. These may be your most commonly used values or those supported by your camera.",
"lensZoom": "Lens zoom", "lensZoom": "Lens zoom",
@ -116,4 +118,4 @@
"tooltipUseLightSensor": "Use lightsensor", "tooltipUseLightSensor": "Use lightsensor",
"tooltipUseCamera": "Use camera", "tooltipUseCamera": "Use camera",
"tooltipOpenSettings": "Open settings" "tooltipOpenSettings": "Open settings"
} }

View file

@ -58,6 +58,8 @@
"ndFiltersFilterDescription": "Sélectionnez les filtres ND à afficher. Ce sont peut-être vos filtres ND les plus couramment utilisés ou ceux qui correspondent à votre lentille.", "ndFiltersFilterDescription": "Sélectionnez les filtres ND à afficher. Ce sont peut-être vos filtres ND les plus couramment utilisés ou ceux qui correspondent à votre lentille.",
"shutterSpeedValues": "Valeurs de la vitesse d'obturation", "shutterSpeedValues": "Valeurs de la vitesse d'obturation",
"shutterSpeedValuesFilterDescription": "Sélectionnez la plage de valeurs de vitesse d'obturation à afficher. Cela est généralement déterminé par le corps de l'appareil que vous utilisez.", "shutterSpeedValuesFilterDescription": "Sélectionnez la plage de valeurs de vitesse d'obturation à afficher. Cela est généralement déterminé par le corps de l'appareil que vous utilisez.",
"shutterSpeedManualShort": "B",
"shutterSpeedManual": "Manuelle",
"isoValues": "Valeurs ISO", "isoValues": "Valeurs ISO",
"isoValuesFilterDescription": "Sélectionnez les valeurs ISO à afficher. Ce sont peut-être vos valeurs les plus couramment utilisées ou celles prises en charge par votre caméra.", "isoValuesFilterDescription": "Sélectionnez les valeurs ISO à afficher. Ce sont peut-être vos valeurs les plus couramment utilisées ou celles prises en charge par votre caméra.",
"lensZoom": "Zoom sur l'objectif", "lensZoom": "Zoom sur l'objectif",

View file

@ -58,6 +58,8 @@
"ndFiltersFilterDescription": "Выберите ND фильтры для отображения. Это могут быть наиболее часто используемые ND фильтры или фильтры, подходящие под ваш объектив.", "ndFiltersFilterDescription": "Выберите ND фильтры для отображения. Это могут быть наиболее часто используемые ND фильтры или фильтры, подходящие под ваш объектив.",
"shutterSpeedValues": "Значения выдержки", "shutterSpeedValues": "Значения выдержки",
"shutterSpeedValuesFilterDescription": "Выберите диапазон значений выдержки. Обычно ограничивается возможностями вашей камеры.", "shutterSpeedValuesFilterDescription": "Выберите диапазон значений выдержки. Обычно ограничивается возможностями вашей камеры.",
"shutterSpeedManualShort": "B",
"shutterSpeedManual": "Ручная",
"isoValues": "Значения ISO", "isoValues": "Значения ISO",
"isoValuesFilterDescription": "Выберите значения ISO для отображения. Это может быть наиболее часто используемые значения или значения, поддерживаемые вашей камерой.", "isoValuesFilterDescription": "Выберите значения ISO для отображения. Это может быть наиболее часто используемые значения или значения, поддерживаемые вашей камерой.",
"lensZoom": "Зум объектива", "lensZoom": "Зум объектива",

View file

@ -58,6 +58,8 @@
"ndFiltersFilterDescription": "选择要显示的 ND 滤镜系数。可能是您最常用的 ND 滤镜,也可能是适合您镜头的减光镜。", "ndFiltersFilterDescription": "选择要显示的 ND 滤镜系数。可能是您最常用的 ND 滤镜,也可能是适合您镜头的减光镜。",
"shutterSpeedValues": "快门速度", "shutterSpeedValues": "快门速度",
"shutterSpeedValuesFilterDescription": "选择要显示的快门速度范围。这通常由您使用的相机机身决定。", "shutterSpeedValuesFilterDescription": "选择要显示的快门速度范围。这通常由您使用的相机机身决定。",
"shutterSpeedManualShort": "B",
"shutterSpeedManual": "手册",
"isoValues": "ISO", "isoValues": "ISO",
"isoValuesFilterDescription": "选择要显示的 ISO 。这些可能是您常用的ISO值也可以是相机支持的ISO范围。", "isoValuesFilterDescription": "选择要显示的 ISO 。这些可能是您常用的ISO值也可以是相机支持的ISO范围。",
"lensZoom": "镜头变焦", "lensZoom": "镜头变焦",

View file

@ -15,9 +15,13 @@ class ExposurePairsListItem<T extends PhotographyStopValue> extends StatelessWid
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final List<Widget> rowChildren = [ final List<Widget> rowChildren = [
Text( Flexible(
value.toString(), child: Text(
style: labelTextStyle(context).copyWith(color: Theme.of(context).colorScheme.onBackground), value.toString(),
style: labelTextStyle(context).copyWith(color: Theme.of(context).colorScheme.onBackground),
softWrap: false,
overflow: TextOverflow.fade,
),
), ),
const SizedBox(width: Dimens.grid8), const SizedBox(width: Dimens.grid8),
ColoredBox( ColoredBox(

View file

@ -158,22 +158,40 @@ class MeteringContainerBuidler extends StatelessWidget {
shutterSpeedOffset = 0; shutterSpeedOffset = 0;
} }
final int itemsCount = min( int itemsCount = min(
apertureValues.length + shutterSpeedOffset, apertureValues.length + shutterSpeedOffset,
shutterSpeedValues.length + apertureOffset, shutterSpeedValues.length + apertureOffset,
) - ) -
max(apertureOffset, shutterSpeedOffset); max(apertureOffset, shutterSpeedOffset);
if (itemsCount <= 0) { if (apertureOffset == apertureValues.length) {
return List.empty(); return List.empty();
} }
final lastPreCalcShutterSpeed =
shutterSpeedValues.elementAtOrNull(itemsCount - 1 + shutterSpeedOffset) ?? shutterSpeedValues.last;
final preCalculatedItemsCount = itemsCount;
if (itemsCount <= 0) {
itemsCount = apertureValues.length;
} else {
itemsCount += (apertureValues.length - 1) - (itemsCount - 1 + apertureOffset);
}
final exposurePairs = List.generate( final exposurePairs = List.generate(
itemsCount, itemsCount,
(index) => ExposurePair( (index) {
apertureValues[index + apertureOffset], final stopDifference = (index - (preCalculatedItemsCount - 1)) / (stopType.index + 1);
shutterSpeedValues[index + shutterSpeedOffset], final newShutterSpeed = log2(lastPreCalcShutterSpeed.rawValue) + stopDifference;
), return ExposurePair(
apertureValues[index + apertureOffset],
shutterSpeedValues.elementAtOrNull(index + shutterSpeedOffset) ??
ShutterSpeedValue(
calcShutterSpeed(newShutterSpeed),
false,
stopDifference == stopDifference.roundToDouble() ? StopType.full : stopType,
),
);
},
growable: false, growable: false,
); );
@ -191,7 +209,9 @@ class MeteringContainerBuidler extends StatelessWidget {
); );
final endCutEV = max( final endCutEV = max(
equipmentApertureValues.last.difference(exposurePairs.last.aperture), equipmentApertureValues.last.difference(exposurePairs.last.aperture),
equipmentShutterSpeedValues.last.difference(exposurePairs.last.shutterSpeed), equipmentShutterSpeedValues.last != ShutterSpeedValue.values.last
? equipmentShutterSpeedValues.last.difference(exposurePairs.last.shutterSpeed)
: double.negativeInfinity,
); );
final startCut = (startCutEV * (stopType.index + 1)).round().clamp(0, itemsCount); final startCut = (startCutEV * (stopType.index + 1)).round().clamp(0, itemsCount);
@ -203,3 +223,12 @@ class MeteringContainerBuidler extends StatelessWidget {
return exposurePairs.sublist(startCut, itemsCount - endCut); return exposurePairs.sublist(startCut, itemsCount - endCut);
} }
} }
double calcShutterSpeed(double stopValue) {
final shutterSpeed = pow(2, stopValue);
if (stopValue < 1.5) {
return (shutterSpeed * 10).round() / 10;
} else {
return shutterSpeed.roundToDouble();
}
}

View file

@ -8,6 +8,8 @@ class RangePickerListTile<T extends PhotographyValue> extends StatelessWidget {
final String description; final String description;
final List<T> selectedValues; final List<T> selectedValues;
final List<T> values; final List<T> values;
final String Function(BuildContext context, T value)? trailingAdapter;
final String Function(BuildContext context, T value)? dialogValueAdapter;
final ValueChanged<List<T>> onChanged; final ValueChanged<List<T>> onChanged;
const RangePickerListTile({ const RangePickerListTile({
@ -16,6 +18,8 @@ class RangePickerListTile<T extends PhotographyValue> extends StatelessWidget {
required this.description, required this.description,
required this.selectedValues, required this.selectedValues,
required this.values, required this.values,
this.trailingAdapter,
this.dialogValueAdapter,
required this.onChanged, required this.onChanged,
super.key, super.key,
}); });
@ -25,7 +29,7 @@ class RangePickerListTile<T extends PhotographyValue> extends StatelessWidget {
return ListTile( return ListTile(
leading: Icon(icon), leading: Icon(icon),
title: Text(title), title: Text(title),
trailing: Text("${selectedValues.first} - ${selectedValues.last}"), trailing: Text(_trailing(context)),
onTap: () { onTap: () {
showDialog<List<T>>( showDialog<List<T>>(
context: context, context: context,
@ -35,7 +39,7 @@ class RangePickerListTile<T extends PhotographyValue> extends StatelessWidget {
description: description, description: description,
values: values, values: values,
selectedValues: selectedValues, selectedValues: selectedValues,
titleAdapter: (_, value) => value.toString(), valueAdapter: (context, value) => dialogValueAdapter?.call(context, value) ?? value.toString(),
), ),
).then((values) { ).then((values) {
if (values != null) { if (values != null) {
@ -45,4 +49,16 @@ class RangePickerListTile<T extends PhotographyValue> extends StatelessWidget {
}, },
); );
} }
String _trailing(BuildContext context) {
final buffer = StringBuffer();
buffer.write(trailingAdapter?.call(context, selectedValues.first) ?? selectedValues.first);
if (selectedValues.first != selectedValues.last) {
buffer.writeAll([
' - ',
trailingAdapter?.call(context, selectedValues.last) ?? selectedValues.last,
]);
}
return buffer.toString();
}
} }

View file

@ -269,6 +269,10 @@ class _AnimatedEquipmentListTiles extends AnimatedWidget {
values: ShutterSpeedValue.values, values: ShutterSpeedValue.values,
selectedValues: equipmentData.shutterSpeedValues, selectedValues: equipmentData.shutterSpeedValues,
onChanged: onShutterSpeedValuesSelected, 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( SliderPickerListTile(
icon: Icons.zoom_in, icon: Icons.zoom_in,

View file

@ -9,7 +9,7 @@ class DialogRangePicker<T extends PhotographyValue> extends StatefulWidget {
final String description; final String description;
final List<T> values; final List<T> values;
final List<T> selectedValues; final List<T> selectedValues;
final String Function(BuildContext context, T value) titleAdapter; final String Function(BuildContext context, T value) valueAdapter;
const DialogRangePicker({ const DialogRangePicker({
required this.icon, required this.icon,
@ -17,7 +17,7 @@ class DialogRangePicker<T extends PhotographyValue> extends StatefulWidget {
required this.description, required this.description,
required this.values, required this.values,
required this.selectedValues, required this.selectedValues,
required this.titleAdapter, required this.valueAdapter,
super.key, super.key,
}); });
@ -52,8 +52,8 @@ class _DialogRangePickerState<T extends PhotographyValue> extends State<DialogRa
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text(widget.values[_start].toString()), Text(widget.valueAdapter(context, widget.values[_start])),
Text(widget.values[_end].toString()), Text(widget.valueAdapter(context, widget.values[_end])),
], ],
), ),
), ),

View file

@ -29,11 +29,11 @@ dependencies:
m3_lightmeter_iap: m3_lightmeter_iap:
git: git:
url: "https://github.com/vodemn/m3_lightmeter_iap" url: "https://github.com/vodemn/m3_lightmeter_iap"
ref: v0.9.2 ref: v0.10.0
m3_lightmeter_resources: m3_lightmeter_resources:
git: git:
url: "https://github.com/vodemn/m3_lightmeter_resources" url: "https://github.com/vodemn/m3_lightmeter_resources"
ref: main ref: v1.2.0
material_color_utilities: 0.5.0 material_color_utilities: 0.5.0
package_info_plus: 4.2.0 package_info_plus: 4.2.0
permission_handler: 10.4.3 permission_handler: 10.4.3

View file

@ -72,7 +72,8 @@ void main() {
testWidgets('Generate light theme screenshots', (tester) async { testWidgets('Generate light theme screenshots', (tester) async {
mockSharedPrefs(ThemeType.light, lightThemeColor); mockSharedPrefs(ThemeType.light, lightThemeColor);
await tester.pumpApplication( await tester.pumpApplication(
films: [_mockFilm], availableFilms: [_mockFilm],
filmsInUse: [_mockFilm],
selectedFilm: _mockFilm, selectedFilm: _mockFilm,
); );
@ -115,7 +116,8 @@ void main() {
(tester) async { (tester) async {
mockSharedPrefs(ThemeType.dark, darkThemeColor); mockSharedPrefs(ThemeType.dark, darkThemeColor);
await tester.pumpApplication( await tester.pumpApplication(
films: [_mockFilm], availableFilms: [_mockFilm],
filmsInUse: [_mockFilm],
selectedFilm: _mockFilm, selectedFilm: _mockFilm,
); );

View file

@ -98,7 +98,7 @@ class _GoldenTestApplicationMockState extends State<GoldenTestApplicationMock> {
child: MockIAPProviders( child: MockIAPProviders(
equipmentProfiles: mockEquipmentProfiles, equipmentProfiles: mockEquipmentProfiles,
selectedEquipmentProfileId: mockEquipmentProfiles.first.id, selectedEquipmentProfileId: mockEquipmentProfiles.first.id,
films: films, selectedFilm: mockFilms.first,
child: Builder( child: Builder(
builder: (context) { builder: (context) {
return MaterialApp( return MaterialApp(

View file

@ -91,7 +91,7 @@ final _mockEquipmentProfiles = [
ndValues: NdValue.values.sublist(0, 3), ndValues: NdValue.values.sublist(0, 3),
shutterSpeedValues: ShutterSpeedValue.values.sublist( shutterSpeedValues: ShutterSpeedValue.values.sublist(
ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(1000, true, StopType.full)), ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(1000, true, StopType.full)),
ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(16, false, StopType.full)) + 1, ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(1, false, StopType.full)) + 1,
), ),
isoValues: const [ isoValues: const [
IsoValue(50, StopType.full), IsoValue(50, StopType.full),

View file

@ -38,7 +38,7 @@ void main() {
expect(find.descendant(of: pickerFinder, matching: find.text(S.current.fastestExposurePair)), findsOneWidget); expect(find.descendant(of: pickerFinder, matching: find.text(S.current.fastestExposurePair)), findsOneWidget);
expect(find.descendant(of: pickerFinder, matching: find.text(S.current.slowestExposurePair)), findsOneWidget); expect(find.descendant(of: pickerFinder, matching: find.text(S.current.slowestExposurePair)), findsOneWidget);
expect(find.descendant(of: pickerFinder, matching: find.text('f/1.0 - 1/2000')), findsOneWidget); expect(find.descendant(of: pickerFinder, matching: find.text('f/1.0 - 1/2000')), findsOneWidget);
expect(find.descendant(of: pickerFinder, matching: find.text('f/45 - 16"')), findsOneWidget); expect(find.descendant(of: pickerFinder, matching: find.text('f/45 - 1"')), findsOneWidget);
}, },
); );
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

File diff suppressed because it is too large Load diff