implemented exposure pairs list

This commit is contained in:
Vadim 2022-10-26 22:49:21 +03:00
parent 9c8809cad6
commit e01ab62fd8
5 changed files with 182 additions and 8 deletions

View file

@ -13,10 +13,21 @@ abstract class PhotographyValue<T> {
T get value; T get value;
} }
extension PhotographyValues<T> on List<PhotographyValue<T>> { extension PhotographyValues<T extends PhotographyValue> on List<T> {
List<PhotographyValue<T>> fullStops() => where((e) => e.stopType == Stop.full).toList(); List<T> whereStopType(Stop stopType) {
switch (stopType) {
List<PhotographyValue<T>> halfStops() => where((e) => e.stopType == Stop.full || e.stopType == Stop.half).toList(); case Stop.full:
return where((e) => e.stopType == Stop.full).toList();
List<PhotographyValue<T>> thirdStops() => where((e) => e.stopType == Stop.full || e.stopType == Stop.third).toList(); case Stop.half:
return where((e) => e.stopType == Stop.full || e.stopType == Stop.half).toList();
case Stop.third:
return where((e) => e.stopType == Stop.full || e.stopType == Stop.third).toList();
}
}
List<T> fullStops() => whereStopType(Stop.full);
List<T> halfStops() => whereStopType(Stop.half);
List<T> thirdStops() => whereStopType(Stop.third);
} }

View file

@ -7,6 +7,7 @@ class Dimens {
static const double grid4 = 4; static const double grid4 = 4;
static const double grid8 = 8; static const double grid8 = 8;
static const double grid16 = 16; static const double grid16 = 16;
static const double grid24 = 24;
static const double paddingM = 16; static const double paddingM = 16;
} }

View file

@ -0,0 +1,54 @@
import 'package:flutter/material.dart';
import 'package:lightmeter/models/photography_value.dart';
import 'package:lightmeter/res/dimens.dart';
class ExposurePaitListItem<T extends PhotographyValue> extends StatelessWidget {
final T value;
final bool tickOnTheLeft;
const ExposurePaitListItem(this.value, {required this.tickOnTheLeft, super.key});
@override
Widget build(BuildContext context) {
final List<Widget> rowChildren = [
Text(
value.toString(),
style: labelTextStyle(context).copyWith(color: Theme.of(context).colorScheme.onBackground),
),
const SizedBox(width: Dimens.grid8),
ColoredBox(
color: Theme.of(context).colorScheme.onBackground,
child: SizedBox(
height: 1,
width: tickLength(),
),
),
];
return Row(
mainAxisAlignment: tickOnTheLeft ? MainAxisAlignment.start : MainAxisAlignment.end,
children: tickOnTheLeft ? rowChildren.reversed.toList() : rowChildren,
);
}
TextStyle labelTextStyle(BuildContext context) {
switch (value.stopType) {
case Stop.full:
return Theme.of(context).textTheme.bodyLarge!;
case Stop.half:
return Theme.of(context).textTheme.bodyMedium!;
case Stop.third:
return Theme.of(context).textTheme.bodySmall!;
}
}
double tickLength() {
switch (value.stopType) {
case Stop.full:
return Dimens.grid24;
case Stop.half:
return Dimens.grid16;
case Stop.third:
return Dimens.grid8;
}
}
}

View file

@ -0,0 +1,100 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:lightmeter/models/photography_value.dart';
import 'package:lightmeter/res/dimens.dart';
import 'package:lightmeter/screens/metering/components/exposure_pairs_list/components/exposure_pair_item.dart';
class ExposurePairsList extends StatelessWidget {
final double ev;
final Stop stopType;
final List<ApertureValue> _apertureValuesList;
final List<ShutterSpeedValue> _shutterSpeedValuesList;
late final int _apertureOffset;
late final int _shutterSpeedOffset;
late final int _itemsCount;
ExposurePairsList({
required this.ev,
required this.stopType,
super.key,
}) : _apertureValuesList = apertureValues.whereStopType(stopType),
_shutterSpeedValuesList = shutterSpeedValues.whereStopType(stopType) {
late final int evSteps;
switch (stopType) {
case Stop.full:
evSteps = ev.floor();
break;
case Stop.half:
evSteps = (ev / 0.5).floor();
break;
case Stop.third:
evSteps = (ev / 0.3).floor();
break;
}
final evOffset = _shutterSpeedValuesList.indexOf(const ShutterSpeedValue(1, false, Stop.full)) - evSteps;
if (evOffset >= 0) {
_apertureOffset = 0;
_shutterSpeedOffset = evOffset;
} else {
_apertureOffset = -evOffset;
_shutterSpeedOffset = 0;
}
_itemsCount = min(
_apertureValuesList.length + _shutterSpeedOffset,
_shutterSpeedValuesList.length + _apertureOffset,
) -
max(
_apertureOffset,
_shutterSpeedOffset,
);
}
@override
Widget build(BuildContext context) {
return Stack(
alignment: Alignment.center,
children: [
Positioned.fill(
child: ListView.builder(
itemCount: _itemsCount,
itemBuilder: (_, index) => Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Align(
alignment: Alignment.centerLeft,
child: ExposurePaitListItem(
_apertureValuesList[index + _apertureOffset],
tickOnTheLeft: false,
),
),
),
const SizedBox(width: Dimens.grid16),
Expanded(
child: Align(
alignment: Alignment.centerLeft,
child: ExposurePaitListItem(
_shutterSpeedValuesList[index + _shutterSpeedOffset],
tickOnTheLeft: true,
),
),
),
],
),
),
),
Positioned(
top: 0,
bottom: 0,
child: ColoredBox(
color: Theme.of(context).colorScheme.onBackground,
child: const SizedBox(width: 1),
),
),
],
);
}
}

View file

@ -1,5 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lightmeter/models/photography_value.dart';
import 'components/exposure_pairs_list/exposure_pairs_list.dart';
import 'components/topbar/topbar.dart'; import 'components/topbar/topbar.dart';
class MeteringScreen extends StatelessWidget { class MeteringScreen extends StatelessWidget {
@ -7,17 +9,23 @@ class MeteringScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
const ev = 0.3;
return Scaffold( return Scaffold(
backgroundColor: Theme.of(context).colorScheme.background, backgroundColor: Theme.of(context).colorScheme.background,
body: Column( body: Column(
children: const [ children: [
MeteringTopBar( const MeteringTopBar(
lux: 283, lux: 283,
ev: 2.3, ev: ev,
iso: 6400, iso: 6400,
nd: 0, nd: 0,
), ),
Spacer() Expanded(
child: ExposurePairsList(
ev: ev,
stopType: Stop.third,
),
),
], ],
), ),
); );