2022-10-24 20:25:38 +00:00
|
|
|
import 'package:flutter/material.dart';
|
2022-10-30 18:30:12 +00:00
|
|
|
import 'package:lightmeter/generated/l10n.dart';
|
2022-10-29 18:02:45 +00:00
|
|
|
import 'package:lightmeter/models/exposure_pair.dart';
|
2022-12-01 20:49:06 +00:00
|
|
|
import 'package:lightmeter/models/photography_value.dart';
|
2022-10-24 20:25:38 +00:00
|
|
|
import 'package:lightmeter/res/dimens.dart';
|
2022-10-29 18:02:45 +00:00
|
|
|
|
2022-12-01 20:49:06 +00:00
|
|
|
import 'components/shared/animated_dialog.dart';
|
|
|
|
import 'components/dialog_picker.dart';
|
2022-10-29 18:02:45 +00:00
|
|
|
import 'components/reading_container.dart';
|
2022-12-01 20:49:06 +00:00
|
|
|
import 'models/reading_value.dart';
|
2022-10-24 20:25:38 +00:00
|
|
|
|
|
|
|
class MeteringTopBar extends StatelessWidget {
|
|
|
|
static const _columnsCount = 3;
|
2022-12-01 20:49:06 +00:00
|
|
|
final _isoDialogKey = GlobalKey<AnimatedDialogState>();
|
2022-10-24 20:25:38 +00:00
|
|
|
|
2022-10-29 18:02:45 +00:00
|
|
|
final ExposurePair? fastest;
|
|
|
|
final ExposurePair? slowest;
|
2022-10-24 20:25:38 +00:00
|
|
|
final double ev;
|
2022-12-01 20:49:06 +00:00
|
|
|
final IsoValue iso;
|
2022-10-24 20:25:38 +00:00
|
|
|
final double nd;
|
|
|
|
|
2022-12-01 20:49:06 +00:00
|
|
|
MeteringTopBar({
|
2022-10-29 18:02:45 +00:00
|
|
|
required this.fastest,
|
|
|
|
required this.slowest,
|
2022-10-24 20:25:38 +00:00
|
|
|
required this.ev,
|
|
|
|
required this.iso,
|
|
|
|
required this.nd,
|
|
|
|
super.key,
|
|
|
|
});
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2022-10-29 11:04:46 +00:00
|
|
|
final columnWidth =
|
|
|
|
(MediaQuery.of(context).size.width - Dimens.paddingM * 2 - Dimens.grid16 * (_columnsCount - 1)) / 3;
|
2022-10-29 11:06:39 +00:00
|
|
|
return ClipRRect(
|
|
|
|
borderRadius: const BorderRadius.only(
|
|
|
|
bottomLeft: Radius.circular(Dimens.borderRadiusL),
|
|
|
|
bottomRight: Radius.circular(Dimens.borderRadiusL),
|
|
|
|
),
|
|
|
|
child: ColoredBox(
|
|
|
|
color: Theme.of(context).colorScheme.surface,
|
|
|
|
child: Padding(
|
|
|
|
padding: const EdgeInsets.all(Dimens.paddingM),
|
|
|
|
child: SafeArea(
|
|
|
|
bottom: false,
|
2022-12-01 20:49:06 +00:00
|
|
|
child: MediaQuery(
|
|
|
|
data: MediaQuery.of(context),
|
|
|
|
child: Row(
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
children: [
|
|
|
|
Expanded(
|
|
|
|
child: Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
|
|
children: [
|
|
|
|
SizedBox(
|
|
|
|
height: columnWidth / 3 * 4,
|
|
|
|
child: ReadingContainer(
|
|
|
|
values: [
|
|
|
|
ReadingValue(
|
|
|
|
label: S.of(context).fastestExposurePair,
|
|
|
|
value: fastest != null
|
|
|
|
? '${fastest!.aperture.toString()} - ${fastest!.shutterSpeed.toString()}'
|
|
|
|
: 'N/A',
|
2022-10-29 11:06:39 +00:00
|
|
|
),
|
2022-12-01 20:49:06 +00:00
|
|
|
ReadingValue(
|
|
|
|
label: S.of(context).slowestExposurePair,
|
|
|
|
value: fastest != null
|
|
|
|
? '${slowest!.aperture.toString()} - ${slowest!.shutterSpeed.toString()}'
|
|
|
|
: 'N/A',
|
|
|
|
),
|
|
|
|
],
|
2022-10-29 11:04:46 +00:00
|
|
|
),
|
2022-12-01 20:49:06 +00:00
|
|
|
),
|
|
|
|
const _InnerPadding(),
|
|
|
|
Row(
|
|
|
|
children: [
|
|
|
|
SizedBox(
|
|
|
|
width: columnWidth,
|
|
|
|
child: ReadingContainer.singleValue(
|
2022-11-29 18:46:23 +00:00
|
|
|
value: ReadingValue(
|
2022-12-01 20:49:06 +00:00
|
|
|
label: 'EV',
|
|
|
|
value: ev.toStringAsFixed(1),
|
2022-11-29 18:46:23 +00:00
|
|
|
),
|
2022-10-29 11:06:39 +00:00
|
|
|
),
|
2022-10-29 11:04:46 +00:00
|
|
|
),
|
2022-12-01 20:49:06 +00:00
|
|
|
const _InnerPadding(),
|
|
|
|
SizedBox(
|
|
|
|
width: columnWidth,
|
|
|
|
child: AnimatedDialog(
|
|
|
|
key: _isoDialogKey,
|
|
|
|
closedChild: ReadingContainer.singleValue(
|
|
|
|
value: ReadingValue(
|
|
|
|
label: S.of(context).iso,
|
|
|
|
value: iso.value.toString(),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
openedChild: MeteringScreenDialogPicker(
|
|
|
|
title: S.of(context).iso,
|
|
|
|
initialValue: iso,
|
|
|
|
values: isoValues,
|
|
|
|
itemTitleBuilder: (context, value) => Text(
|
|
|
|
value.value.toString(),
|
|
|
|
style: value.stopType == StopType.full
|
|
|
|
? Theme.of(context).textTheme.bodyLarge
|
|
|
|
: Theme.of(context).textTheme.bodySmall,
|
|
|
|
),
|
|
|
|
onCancel: () {
|
|
|
|
_isoDialogKey.currentState?.close();
|
|
|
|
},
|
|
|
|
onSelect: (value) {
|
|
|
|
_isoDialogKey.currentState?.close();
|
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
],
|
|
|
|
),
|
2022-10-29 11:06:39 +00:00
|
|
|
),
|
2022-12-01 20:49:06 +00:00
|
|
|
const _InnerPadding(),
|
|
|
|
SizedBox(
|
|
|
|
width: columnWidth,
|
|
|
|
child: Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
|
|
children: [
|
|
|
|
AnimatedDialog(
|
|
|
|
openedSize: Size(
|
|
|
|
MediaQuery.of(context).size.width - Dimens.paddingM * 2,
|
|
|
|
(MediaQuery.of(context).size.width - Dimens.paddingM * 2) / 3 * 4,
|
|
|
|
),
|
|
|
|
child: const AspectRatio(
|
|
|
|
aspectRatio: 3 / 4,
|
|
|
|
child: ColoredBox(color: Colors.black),
|
|
|
|
),
|
2022-10-29 11:06:39 +00:00
|
|
|
),
|
2022-12-01 20:49:06 +00:00
|
|
|
const _InnerPadding(),
|
|
|
|
ReadingContainer.singleValue(
|
2022-11-29 18:46:23 +00:00
|
|
|
value: ReadingValue(
|
|
|
|
label: 'ND',
|
|
|
|
value: nd.toString(),
|
|
|
|
),
|
2022-10-29 11:06:39 +00:00
|
|
|
),
|
2022-12-01 20:49:06 +00:00
|
|
|
],
|
|
|
|
),
|
2022-10-29 11:06:39 +00:00
|
|
|
),
|
2022-12-01 20:49:06 +00:00
|
|
|
],
|
|
|
|
),
|
2022-10-29 11:06:39 +00:00
|
|
|
),
|
2022-10-24 20:25:38 +00:00
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class _InnerPadding extends SizedBox {
|
2022-10-29 11:04:46 +00:00
|
|
|
const _InnerPadding() : super(height: Dimens.grid16, width: Dimens.grid16);
|
2022-10-24 20:25:38 +00:00
|
|
|
}
|