Added histogram to MeteringScreenLayoutConfig

This commit is contained in:
Vadim 2023-08-06 12:16:50 +02:00
parent 680b9a1237
commit 7192e2e8d3
10 changed files with 81 additions and 37 deletions

View file

@ -1,11 +1,13 @@
enum MeteringScreenLayoutFeature { extremeExposurePairs, filmPicker } enum MeteringScreenLayoutFeature { extremeExposurePairs, filmPicker, histogram }
typedef MeteringScreenLayoutConfig = Map<MeteringScreenLayoutFeature, bool>; typedef MeteringScreenLayoutConfig = Map<MeteringScreenLayoutFeature, bool>;
extension MeteringScreenLayoutConfigJson on MeteringScreenLayoutConfig { extension MeteringScreenLayoutConfigJson on MeteringScreenLayoutConfig {
static MeteringScreenLayoutConfig fromJson(Map<String, dynamic> data) => data.map( static MeteringScreenLayoutConfig fromJson(Map<String, dynamic> data) =>
(key, value) => MapEntry(MeteringScreenLayoutFeature.values[int.parse(key)], value as bool), <MeteringScreenLayoutFeature, bool>{
); for (final f in MeteringScreenLayoutFeature.values)
f: data[f.index.toString()] as bool? ?? true
};
Map<String, dynamic> toJson() => map((key, value) => MapEntry(key.index.toString(), value)); Map<String, dynamic> toJson() => map((key, value) => MapEntry(key.index.toString(), value));
} }

View file

@ -97,6 +97,7 @@ class UserPreferencesService {
return { return {
MeteringScreenLayoutFeature.extremeExposurePairs: true, MeteringScreenLayoutFeature.extremeExposurePairs: true,
MeteringScreenLayoutFeature.filmPicker: true, MeteringScreenLayoutFeature.filmPicker: true,
MeteringScreenLayoutFeature.histogram: true,
}; };
} }
} }

View file

@ -38,6 +38,7 @@
"meteringScreenLayoutHint": "Hide elements on the metering screen that you don't need so that they don't waste exposure pairs list space.", "meteringScreenLayoutHint": "Hide elements on the metering screen that you don't need so that they don't waste exposure pairs list space.",
"meteringScreenFeatureExtremeExposurePairs": "Fastest & shortest exposure pairs", "meteringScreenFeatureExtremeExposurePairs": "Fastest & shortest exposure pairs",
"meteringScreenFeatureFilmPicker": "Film picker", "meteringScreenFeatureFilmPicker": "Film picker",
"meteringScreenFeatureHistogram": "Histogram",
"film": "Film", "film": "Film",
"equipment": "Equipment", "equipment": "Equipment",
"equipmentProfileName": "Equipment profile name", "equipmentProfileName": "Equipment profile name",

View file

@ -38,6 +38,7 @@
"meteringScreenLayoutHint": "Masquer les éléments sur l'écran de mesure dont vous n'avez pas besoin pour qu'ils ne gaspillent pas de l'espace dans les paires d'exposition.", "meteringScreenLayoutHint": "Masquer les éléments sur l'écran de mesure dont vous n'avez pas besoin pour qu'ils ne gaspillent pas de l'espace dans les paires d'exposition.",
"meteringScreenFeatureExtremeExposurePairs": "Paires d'exposition les plus rapides et les plus courtes", "meteringScreenFeatureExtremeExposurePairs": "Paires d'exposition les plus rapides et les plus courtes",
"meteringScreenFeatureFilmPicker": "Sélecteur de film", "meteringScreenFeatureFilmPicker": "Sélecteur de film",
"meteringScreenFeatureHistogram": "Histogramme",
"film": "Pellicule", "film": "Pellicule",
"equipment": "Équipement", "equipment": "Équipement",
"equipmentProfileName": "Nom du profil de l'équipement", "equipmentProfileName": "Nom du profil de l'équipement",

View file

@ -38,6 +38,7 @@
"meteringScreenLayoutHint": "Здесь вы можете скрыть некоторые ненужные или неиспользуемые элементы с главного экрана.", "meteringScreenLayoutHint": "Здесь вы можете скрыть некоторые ненужные или неиспользуемые элементы с главного экрана.",
"meteringScreenFeatureExtremeExposurePairs": "Длинная и короткая выдержки", "meteringScreenFeatureExtremeExposurePairs": "Длинная и короткая выдержки",
"meteringScreenFeatureFilmPicker": "Выбор пленки", "meteringScreenFeatureFilmPicker": "Выбор пленки",
"meteringScreenFeatureHistogram": "Гистограмма",
"film": "Пленка", "film": "Пленка",
"equipment": "Оборудование", "equipment": "Оборудование",
"equipmentProfileName": "Название профиля", "equipmentProfileName": "Название профиля",

View file

@ -38,6 +38,7 @@
"meteringScreenLayoutHint": "隐藏不需要的元素,以免浪费曝光列表空间", "meteringScreenLayoutHint": "隐藏不需要的元素,以免浪费曝光列表空间",
"meteringScreenFeatureExtremeExposurePairs": "最快 & 最慢曝光组合", "meteringScreenFeatureExtremeExposurePairs": "最快 & 最慢曝光组合",
"meteringScreenFeatureFilmPicker": "胶片选择", "meteringScreenFeatureFilmPicker": "胶片选择",
"meteringScreenFeatureHistogram": "直方图",
"film": "胶片", "film": "胶片",
"equipment": "设备", "equipment": "设备",
"equipmentProfileName": "设备配置名称", "equipmentProfileName": "设备配置名称",

View file

@ -1,6 +1,8 @@
import 'package:camera/camera.dart'; import 'package:camera/camera.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
import 'package:lightmeter/platform_config.dart'; import 'package:lightmeter/platform_config.dart';
import 'package:lightmeter/providers/metering_screen_layout_provider.dart';
import 'package:lightmeter/res/dimens.dart'; import 'package:lightmeter/res/dimens.dart';
import 'package:lightmeter/screens/metering/components/camera_container/components/camera_preview/components/camera_view/widget_camera_view.dart'; import 'package:lightmeter/screens/metering/components/camera_container/components/camera_preview/components/camera_view/widget_camera_view.dart';
import 'package:lightmeter/screens/metering/components/camera_container/components/camera_preview/components/camera_view_placeholder/widget_placeholder_camera_view.dart'; import 'package:lightmeter/screens/metering/components/camera_container/components/camera_preview/components/camera_view_placeholder/widget_placeholder_camera_view.dart';
@ -31,20 +33,24 @@ class _CameraPreviewState extends State<CameraPreview> {
child: widget.controller != null child: widget.controller != null
? ValueListenableBuilder<CameraValue>( ? ValueListenableBuilder<CameraValue>(
valueListenable: widget.controller!, valueListenable: widget.controller!,
builder: (_, __, ___) => Stack( builder: (_, __, ___) => widget.controller!.value.isInitialized
alignment: Alignment.bottomCenter, ? Stack(
children: [ alignment: Alignment.bottomCenter,
if (widget.controller!.value.isInitialized) children: [
CameraView(controller: widget.controller!), CameraView(controller: widget.controller!),
if (widget.controller!.value.isInitialized) if (MeteringScreenLayout.featureOf(
Positioned( context,
left: 0, MeteringScreenLayoutFeature.histogram,
right: 0, ))
bottom: Dimens.borderRadiusM, Positioned(
child: CameraHistogram(controller: widget.controller!), left: 0,
), right: 0,
], bottom: Dimens.borderRadiusM,
), child: CameraHistogram(controller: widget.controller!),
),
],
)
: const SizedBox.shrink(),
) )
: CameraViewPlaceholder(error: widget.error), : CameraViewPlaceholder(error: widget.error),
), ),

View file

@ -71,6 +71,8 @@ class _MeteringScreenLayoutFeaturesDialogState extends State<MeteringScreenLayou
return S.of(context).meteringScreenFeatureExtremeExposurePairs; return S.of(context).meteringScreenFeatureExtremeExposurePairs;
case MeteringScreenLayoutFeature.filmPicker: case MeteringScreenLayoutFeature.filmPicker:
return S.of(context).meteringScreenFeatureFilmPicker; return S.of(context).meteringScreenFeatureFilmPicker;
case MeteringScreenLayoutFeature.histogram:
return S.of(context).meteringScreenFeatureHistogram;
} }
} }
} }

View file

@ -2,30 +2,56 @@ import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
void main() { void main() {
test('fromJson', () { group(
expect( 'fromJson()',
MeteringScreenLayoutConfigJson.fromJson({'0': true, '1': true}), () {
{ test('All keys', () {
MeteringScreenLayoutFeature.extremeExposurePairs: true, expect(
MeteringScreenLayoutFeature.filmPicker: true, MeteringScreenLayoutConfigJson.fromJson(
}, {
); '0': true,
expect( '1': true,
MeteringScreenLayoutConfigJson.fromJson({'0': false, '1': false}), '2': true,
{ },
MeteringScreenLayoutFeature.extremeExposurePairs: false, ),
MeteringScreenLayoutFeature.filmPicker: false, {
}, MeteringScreenLayoutFeature.extremeExposurePairs: true,
); MeteringScreenLayoutFeature.filmPicker: true,
}); MeteringScreenLayoutFeature.histogram: true,
},
);
});
test('Legacy (no equipment profiles)', () {
expect(
MeteringScreenLayoutConfigJson.fromJson(
{
'0': true,
'1': true,
},
),
{
MeteringScreenLayoutFeature.extremeExposurePairs: true,
MeteringScreenLayoutFeature.filmPicker: true,
MeteringScreenLayoutFeature.histogram: true,
},
);
});
},
);
test('toJson', () { test('toJson', () {
expect( expect(
{ {
MeteringScreenLayoutFeature.extremeExposurePairs: true, MeteringScreenLayoutFeature.extremeExposurePairs: true,
MeteringScreenLayoutFeature.filmPicker: true, MeteringScreenLayoutFeature.filmPicker: true,
MeteringScreenLayoutFeature.histogram: true,
}.toJson(), }.toJson(),
{'0': true, '1': true}, {
'0': true,
'1': true,
'2': true,
},
); );
}); });
} }

View file

@ -193,6 +193,7 @@ void main() {
{ {
MeteringScreenLayoutFeature.extremeExposurePairs: true, MeteringScreenLayoutFeature.extremeExposurePairs: true,
MeteringScreenLayoutFeature.filmPicker: true, MeteringScreenLayoutFeature.filmPicker: true,
MeteringScreenLayoutFeature.histogram: true,
}, },
); );
}); });
@ -206,6 +207,7 @@ void main() {
{ {
MeteringScreenLayoutFeature.extremeExposurePairs: false, MeteringScreenLayoutFeature.extremeExposurePairs: false,
MeteringScreenLayoutFeature.filmPicker: true, MeteringScreenLayoutFeature.filmPicker: true,
MeteringScreenLayoutFeature.histogram: true,
}, },
); );
}); });
@ -214,17 +216,18 @@ void main() {
when( when(
() => sharedPreferences.setString( () => sharedPreferences.setString(
UserPreferencesService.meteringScreenLayoutKey, UserPreferencesService.meteringScreenLayoutKey,
"""{"0":false,"1":true}""", """{"0":false,"1":true,"2":true}""",
), ),
).thenAnswer((_) => Future.value(true)); ).thenAnswer((_) => Future.value(true));
service.meteringScreenLayout = { service.meteringScreenLayout = {
MeteringScreenLayoutFeature.extremeExposurePairs: false, MeteringScreenLayoutFeature.extremeExposurePairs: false,
MeteringScreenLayoutFeature.filmPicker: true, MeteringScreenLayoutFeature.filmPicker: true,
MeteringScreenLayoutFeature.histogram: true,
}; };
verify( verify(
() => sharedPreferences.setString( () => sharedPreferences.setString(
UserPreferencesService.meteringScreenLayoutKey, UserPreferencesService.meteringScreenLayoutKey,
"""{"0":false,"1":true}""", """{"0":false,"1":true,"2":true}""",
), ),
).called(1); ).called(1);
}); });