m3_lightmeter/lib/screens/metering/metering_screen.dart

149 lines
4.6 KiB
Dart
Raw Normal View History

2022-10-24 20:25:38 +00:00
import 'package:flutter/material.dart';
2022-10-29 18:02:45 +00:00
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:lightmeter/res/dimens.dart';
2022-10-24 20:25:38 +00:00
import 'components/animated_surface/animated_surface.dart';
2022-10-29 11:01:15 +00:00
import 'components/bottom_controls/bottom_controls.dart';
2022-10-26 19:49:21 +00:00
import 'components/exposure_pairs_list/exposure_pairs_list.dart';
2022-10-24 20:25:38 +00:00
import 'components/topbar/topbar.dart';
2022-10-29 18:02:45 +00:00
import 'metering_bloc.dart';
import 'metering_event.dart';
2022-10-29 18:02:45 +00:00
import 'metering_state.dart';
2022-10-24 20:25:38 +00:00
class MeteringScreen extends StatefulWidget {
2022-10-24 20:25:38 +00:00
const MeteringScreen({super.key});
@override
State<MeteringScreen> createState() => _MeteringScreenState();
}
class _MeteringScreenState extends State<MeteringScreen> with TickerProviderStateMixin {
final _topBarKey = GlobalKey(debugLabel: 'TopBarKey');
final _middleAreaKey = GlobalKey(debugLabel: 'MiddleAreaKey');
final _bottomBarKey = GlobalKey(debugLabel: 'BottomBarKey');
late final AnimationController _animationController;
bool _secondBuild = false;
late double _topBarHeight;
late double _middleAreaHeight;
late double _bottomBarHeight;
@override
void initState() {
super.initState();
// 0 - collapsed
// 1 - expanded
_animationController = AnimationController(
value: 0,
duration: Dimens.durationL,
vsync: this,
);
WidgetsBinding.instance.addPostFrameCallback((_) {
_topBarHeight = _getHeight(_topBarKey);
_middleAreaHeight = _getHeight(_middleAreaKey);
_bottomBarHeight = _getHeight(_bottomBarKey);
setState(() {
_secondBuild = true;
});
});
}
2022-10-24 20:25:38 +00:00
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).colorScheme.background,
2022-10-29 18:02:45 +00:00
body: BlocBuilder<MeteringBloc, MeteringState>(
builder: (context, state) {
return Stack(
2022-10-29 18:02:45 +00:00
children: [
Column(
children: [
if (_secondBuild) SizedBox(height: _topBarHeight) else _topBar(state),
Expanded(
key: _middleAreaKey,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: Dimens.paddingM),
child: Row(
children: [
Expanded(
flex: 2,
child: ExposurePairsList(state.exposurePairs),
),
const SizedBox(width: Dimens.grid16),
const Spacer()
],
2022-10-29 18:02:45 +00:00
),
),
2022-10-29 18:02:45 +00:00
),
if (_secondBuild) SizedBox(height: _bottomBarHeight) else _bottomBar(),
],
2022-10-29 18:02:45 +00:00
),
if (_secondBuild)
Positioned(
left: 0,
top: 0,
right: 0,
child: MeteringScreenAnimatedSurface.top(
controller: _animationController,
areaHeight: _topBarHeight,
overflowSize: _middleAreaHeight / 2,
child: _topBar(state),
),
),
if (_secondBuild)
Positioned(
left: 0,
right: 0,
bottom: 0,
child: MeteringScreenAnimatedSurface.bottom(
controller: _animationController,
areaHeight: _bottomBarHeight,
overflowSize: _middleAreaHeight / 2,
child: _bottomBar(),
),
),
2022-10-29 18:02:45 +00:00
],
);
},
2022-10-24 20:25:38 +00:00
),
);
}
Widget _topBar(MeteringState state) {
return MeteringTopBar(
key: _topBarKey,
fastest: state.fastest,
slowest: state.slowest,
ev: state.ev,
iso: state.iso,
nd: state.nd,
);
}
Widget _bottomBar() {
return MeteringBottomControls(
key: _bottomBarKey,
onSourceChanged: () {},
onMeasure: () => context.read<MeteringBloc>().add(const MeasureEvent()),
onSettings: () {
// Navigator.push(context, MaterialPageRoute(builder: (_) => const SettingsScreen()));
_toggleAnimation();
},
);
}
double _getHeight(GlobalKey key) => key.currentContext!.size!.height;
void _toggleAnimation() {
if (_animationController.isAnimating) {
return;
}
if (_animationController.status != AnimationStatus.dismissed) {
_animationController.reverse();
} else if (_animationController.status != AnimationStatus.completed) {
_animationController.forward();
}
}
2022-10-24 20:25:38 +00:00
}