mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-22 15:30:59 +00:00
reused BottomControlsBar
This commit is contained in:
parent
7eb0ecde7f
commit
338a333a38
6 changed files with 135 additions and 176 deletions
|
@ -1,48 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
|
||||||
|
|
||||||
import 'package:lightmeter/screens/metering/components/bottom_controls/widget_bottom_controls.dart';
|
|
||||||
|
|
||||||
class MeteringBottomControlsProvider extends StatelessWidget {
|
|
||||||
final double? ev;
|
|
||||||
final double? ev100;
|
|
||||||
final bool isMetering;
|
|
||||||
final VoidCallback? onSwitchEvSourceType;
|
|
||||||
final VoidCallback onMeasure;
|
|
||||||
final VoidCallback onSettings;
|
|
||||||
|
|
||||||
const MeteringBottomControlsProvider({
|
|
||||||
required this.ev,
|
|
||||||
required this.ev100,
|
|
||||||
required this.isMetering,
|
|
||||||
required this.onSwitchEvSourceType,
|
|
||||||
required this.onMeasure,
|
|
||||||
required this.onSettings,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final scheme = Theme.of(context).colorScheme;
|
|
||||||
return IconButtonTheme(
|
|
||||||
data: IconButtonThemeData(
|
|
||||||
style: ButtonStyle(
|
|
||||||
backgroundColor: MaterialStatePropertyAll(scheme.surface),
|
|
||||||
elevation: const MaterialStatePropertyAll(4),
|
|
||||||
iconColor: MaterialStatePropertyAll(scheme.onSurface),
|
|
||||||
shadowColor: const MaterialStatePropertyAll(Colors.transparent),
|
|
||||||
surfaceTintColor: MaterialStatePropertyAll(scheme.surfaceTint),
|
|
||||||
fixedSize: const MaterialStatePropertyAll(Size(Dimens.grid48, Dimens.grid48)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: MeteringBottomControls(
|
|
||||||
ev: ev,
|
|
||||||
ev100: ev100,
|
|
||||||
isMetering: isMetering,
|
|
||||||
onSwitchEvSourceType: onSwitchEvSourceType,
|
|
||||||
onMeasure: onMeasure,
|
|
||||||
onSettings: onSettings,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:lightmeter/data/models/ev_source_type.dart';
|
import 'package:lightmeter/data/models/ev_source_type.dart';
|
||||||
import 'package:lightmeter/generated/l10n.dart';
|
import 'package:lightmeter/generated/l10n.dart';
|
||||||
import 'package:lightmeter/providers/user_preferences_provider.dart';
|
import 'package:lightmeter/providers/user_preferences_provider.dart';
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
|
||||||
import 'package:lightmeter/screens/metering/components/bottom_controls/components/measure_button/widget_button_measure.dart';
|
import 'package:lightmeter/screens/metering/components/bottom_controls/components/measure_button/widget_button_measure.dart';
|
||||||
|
import 'package:lightmeter/screens/shared/bottom_controls_bar/widget_bottom_controls_bar.dart';
|
||||||
|
|
||||||
class MeteringBottomControls extends StatelessWidget {
|
class MeteringBottomControls extends StatelessWidget {
|
||||||
final double? ev;
|
final double? ev;
|
||||||
|
@ -25,58 +25,30 @@ class MeteringBottomControls extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ClipRRect(
|
return BottomControlsBar(
|
||||||
borderRadius: const BorderRadius.only(
|
left: onSwitchEvSourceType != null
|
||||||
topLeft: Radius.circular(Dimens.borderRadiusL),
|
? IconButton(
|
||||||
topRight: Radius.circular(Dimens.borderRadiusL),
|
onPressed: onSwitchEvSourceType,
|
||||||
|
icon: Icon(
|
||||||
|
UserPreferencesProvider.evSourceTypeOf(context) != EvSourceType.camera
|
||||||
|
? Icons.camera_rear
|
||||||
|
: Icons.wb_incandescent,
|
||||||
|
),
|
||||||
|
tooltip: UserPreferencesProvider.evSourceTypeOf(context) != EvSourceType.camera
|
||||||
|
? S.of(context).tooltipUseCamera
|
||||||
|
: S.of(context).tooltipUseLightSensor,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
center: MeteringMeasureButton(
|
||||||
|
ev: ev,
|
||||||
|
ev100: ev100,
|
||||||
|
isMetering: isMetering,
|
||||||
|
onTap: onMeasure,
|
||||||
),
|
),
|
||||||
child: ColoredBox(
|
right: IconButton(
|
||||||
color: Theme.of(context).colorScheme.surface,
|
onPressed: onSettings,
|
||||||
child: SafeArea(
|
icon: const Icon(Icons.settings),
|
||||||
top: false,
|
tooltip: S.of(context).tooltipOpenSettings,
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: Dimens.paddingL),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
||||||
children: [
|
|
||||||
if (onSwitchEvSourceType != null)
|
|
||||||
Expanded(
|
|
||||||
child: Center(
|
|
||||||
child: IconButton(
|
|
||||||
onPressed: onSwitchEvSourceType,
|
|
||||||
icon: Icon(
|
|
||||||
UserPreferencesProvider.evSourceTypeOf(context) != EvSourceType.camera
|
|
||||||
? Icons.camera_rear
|
|
||||||
: Icons.wb_incandescent,
|
|
||||||
),
|
|
||||||
tooltip:
|
|
||||||
UserPreferencesProvider.evSourceTypeOf(context) != EvSourceType.camera
|
|
||||||
? S.of(context).tooltipUseCamera
|
|
||||||
: S.of(context).tooltipUseLightSensor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
else
|
|
||||||
const Spacer(),
|
|
||||||
MeteringMeasureButton(
|
|
||||||
ev: ev,
|
|
||||||
ev100: ev100,
|
|
||||||
isMetering: isMetering,
|
|
||||||
onTap: onMeasure,
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Center(
|
|
||||||
child: IconButton(
|
|
||||||
onPressed: onSettings,
|
|
||||||
icon: const Icon(Icons.settings),
|
|
||||||
tooltip: S.of(context).tooltipOpenSettings,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import 'package:lightmeter/providers/equipment_profile_provider.dart';
|
||||||
import 'package:lightmeter/providers/services_provider.dart';
|
import 'package:lightmeter/providers/services_provider.dart';
|
||||||
import 'package:lightmeter/providers/user_preferences_provider.dart';
|
import 'package:lightmeter/providers/user_preferences_provider.dart';
|
||||||
import 'package:lightmeter/screens/metering/bloc_metering.dart';
|
import 'package:lightmeter/screens/metering/bloc_metering.dart';
|
||||||
import 'package:lightmeter/screens/metering/components/bottom_controls/provider_bottom_controls.dart';
|
import 'package:lightmeter/screens/metering/components/bottom_controls/widget_bottom_controls.dart';
|
||||||
import 'package:lightmeter/screens/metering/components/camera_container/provider_container_camera.dart';
|
import 'package:lightmeter/screens/metering/components/camera_container/provider_container_camera.dart';
|
||||||
import 'package:lightmeter/screens/metering/components/light_sensor_container/provider_container_light_sensor.dart';
|
import 'package:lightmeter/screens/metering/components/light_sensor_container/provider_container_light_sensor.dart';
|
||||||
import 'package:lightmeter/screens/metering/event_metering.dart';
|
import 'package:lightmeter/screens/metering/event_metering.dart';
|
||||||
|
@ -39,7 +39,7 @@ class MeteringScreen extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
BlocBuilder<MeteringBloc, MeteringState>(
|
BlocBuilder<MeteringBloc, MeteringState>(
|
||||||
builder: (context, state) => MeteringBottomControlsProvider(
|
builder: (context, state) => MeteringBottomControls(
|
||||||
ev: state is MeteringDataState ? state.ev : null,
|
ev: state is MeteringDataState ? state.ev : null,
|
||||||
ev100: state is MeteringDataState ? state.ev100 : null,
|
ev100: state is MeteringDataState ? state.ev100 : null,
|
||||||
isMetering: state.isMetering,
|
isMetering: state.isMetering,
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:lightmeter/res/dimens.dart';
|
||||||
|
|
||||||
|
class BottomControlsBar extends StatelessWidget {
|
||||||
|
final Widget center;
|
||||||
|
final IconButton? left;
|
||||||
|
final IconButton? right;
|
||||||
|
|
||||||
|
const BottomControlsBar({
|
||||||
|
required this.center,
|
||||||
|
this.left,
|
||||||
|
this.right,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final scheme = Theme.of(context).colorScheme;
|
||||||
|
return IconButtonTheme(
|
||||||
|
data: IconButtonThemeData(
|
||||||
|
style: ButtonStyle(
|
||||||
|
backgroundColor: MaterialStatePropertyAll(scheme.surface),
|
||||||
|
elevation: const MaterialStatePropertyAll(4),
|
||||||
|
iconColor: MaterialStatePropertyAll(scheme.onSurface),
|
||||||
|
shadowColor: const MaterialStatePropertyAll(Colors.transparent),
|
||||||
|
surfaceTintColor: MaterialStatePropertyAll(scheme.surfaceTint),
|
||||||
|
fixedSize: const MaterialStatePropertyAll(Size(Dimens.grid48, Dimens.grid48)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(Dimens.borderRadiusL),
|
||||||
|
topRight: Radius.circular(Dimens.borderRadiusL),
|
||||||
|
),
|
||||||
|
child: ColoredBox(
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
child: SafeArea(
|
||||||
|
top: false,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: Dimens.paddingL),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
if (left != null) Expanded(child: Center(child: left)) else const Spacer(),
|
||||||
|
center,
|
||||||
|
if (right != null) Expanded(child: Center(child: right)) else const Spacer(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:lightmeter/data/models/exposure_pair.dart';
|
import 'package:lightmeter/data/models/exposure_pair.dart';
|
||||||
import 'package:lightmeter/interactors/metering_interactor.dart';
|
import 'package:lightmeter/interactors/metering_interactor.dart';
|
||||||
import 'package:lightmeter/providers/services_provider.dart';
|
import 'package:lightmeter/providers/services_provider.dart';
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
|
||||||
import 'package:lightmeter/screens/timer/bloc_timer.dart';
|
import 'package:lightmeter/screens/timer/bloc_timer.dart';
|
||||||
import 'package:lightmeter/screens/timer/screen_timer.dart';
|
import 'package:lightmeter/screens/timer/screen_timer.dart';
|
||||||
|
|
||||||
|
@ -16,36 +15,23 @@ class TimerFlow extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final scheme = Theme.of(context).colorScheme;
|
return MeteringInteractorProvider(
|
||||||
return IconButtonTheme(
|
data: MeteringInteractor(
|
||||||
data: IconButtonThemeData(
|
ServicesProvider.of(context).userPreferencesService,
|
||||||
style: ButtonStyle(
|
ServicesProvider.of(context).caffeineService,
|
||||||
backgroundColor: MaterialStatePropertyAll(scheme.surface),
|
ServicesProvider.of(context).hapticsService,
|
||||||
elevation: const MaterialStatePropertyAll(4),
|
ServicesProvider.of(context).permissionsService,
|
||||||
iconColor: MaterialStatePropertyAll(scheme.onSurface),
|
ServicesProvider.of(context).lightSensorService,
|
||||||
shadowColor: const MaterialStatePropertyAll(Colors.transparent),
|
ServicesProvider.of(context).volumeEventsService,
|
||||||
surfaceTintColor: MaterialStatePropertyAll(scheme.surfaceTint),
|
)..initialize(),
|
||||||
fixedSize: const MaterialStatePropertyAll(Size(Dimens.grid48, Dimens.grid48)),
|
child: BlocProvider(
|
||||||
|
create: (context) => TimerBloc(
|
||||||
|
MeteringInteractorProvider.of(context),
|
||||||
|
_duration,
|
||||||
),
|
),
|
||||||
),
|
child: TimerScreen(
|
||||||
child: MeteringInteractorProvider(
|
exposurePair: exposurePair,
|
||||||
data: MeteringInteractor(
|
duration: _duration,
|
||||||
ServicesProvider.of(context).userPreferencesService,
|
|
||||||
ServicesProvider.of(context).caffeineService,
|
|
||||||
ServicesProvider.of(context).hapticsService,
|
|
||||||
ServicesProvider.of(context).permissionsService,
|
|
||||||
ServicesProvider.of(context).lightSensorService,
|
|
||||||
ServicesProvider.of(context).volumeEventsService,
|
|
||||||
)..initialize(),
|
|
||||||
child: BlocProvider(
|
|
||||||
create: (context) => TimerBloc(
|
|
||||||
MeteringInteractorProvider.of(context),
|
|
||||||
_duration,
|
|
||||||
),
|
|
||||||
child: TimerScreen(
|
|
||||||
exposurePair: exposurePair,
|
|
||||||
duration: _duration,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:lightmeter/data/models/exposure_pair.dart';
|
import 'package:lightmeter/data/models/exposure_pair.dart';
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
import 'package:lightmeter/res/dimens.dart';
|
||||||
|
import 'package:lightmeter/screens/shared/bottom_controls_bar/widget_bottom_controls_bar.dart';
|
||||||
import 'package:lightmeter/screens/timer/bloc_timer.dart';
|
import 'package:lightmeter/screens/timer/bloc_timer.dart';
|
||||||
import 'package:lightmeter/screens/timer/components/text/widget_text_timer.dart';
|
import 'package:lightmeter/screens/timer/components/text/widget_text_timer.dart';
|
||||||
import 'package:lightmeter/screens/timer/components/timeline/widget_timeline_timer.dart';
|
import 'package:lightmeter/screens/timer/components/timeline/widget_timeline_timer.dart';
|
||||||
|
@ -77,14 +78,15 @@ class _TimerScreenState extends State<TimerScreen> with TickerProviderStateMixin
|
||||||
actions: [if (Navigator.of(context).canPop()) const CloseButton()],
|
actions: [if (Navigator.of(context).canPop()) const CloseButton()],
|
||||||
),
|
),
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
|
bottom: false,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Padding(
|
child: Column(
|
||||||
padding: const EdgeInsets.all(Dimens.paddingL),
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
child: Column(
|
children: [
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
const Spacer(),
|
||||||
children: [
|
Padding(
|
||||||
const Spacer(),
|
padding: const EdgeInsets.all(Dimens.paddingL),
|
||||||
SizedBox.fromSize(
|
child: SizedBox.fromSize(
|
||||||
size: Size.square(MediaQuery.sizeOf(context).width - Dimens.paddingL * 4),
|
size: Size.square(MediaQuery.sizeOf(context).width - Dimens.paddingL * 4),
|
||||||
child: ValueListenableBuilder(
|
child: ValueListenableBuilder(
|
||||||
valueListenable: timelineAnimation,
|
valueListenable: timelineAnimation,
|
||||||
|
@ -97,44 +99,36 @@ class _TimerScreenState extends State<TimerScreen> with TickerProviderStateMixin
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
),
|
||||||
Row(
|
const Spacer(),
|
||||||
children: [
|
BottomControlsBar(
|
||||||
Expanded(
|
left: IconButton(
|
||||||
child: Center(
|
onPressed: () {
|
||||||
child: IconButton(
|
context.read<TimerBloc>().add(const ResetTimerEvent());
|
||||||
onPressed: () {
|
},
|
||||||
context.read<TimerBloc>().add(const ResetTimerEvent());
|
icon: const Icon(Icons.restore),
|
||||||
},
|
|
||||||
icon: const Icon(Icons.restore),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox.fromSize(
|
|
||||||
size: const Size.square(Dimens.grid72),
|
|
||||||
child: BlocBuilder<TimerBloc, TimerState>(
|
|
||||||
builder: (_, state) => FloatingActionButton(
|
|
||||||
shape: state is TimerResumedState ? null : const CircleBorder(),
|
|
||||||
onPressed: () {
|
|
||||||
if (timelineAnimation.value == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final event =
|
|
||||||
state is TimerStoppedState ? const StartTimerEvent() : const StopTimerEvent();
|
|
||||||
context.read<TimerBloc>().add(event);
|
|
||||||
},
|
|
||||||
child: AnimatedIcon(
|
|
||||||
icon: AnimatedIcons.play_pause,
|
|
||||||
progress: startStopIconAnimation,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Spacer(),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
],
|
center: SizedBox.fromSize(
|
||||||
),
|
size: const Size.square(Dimens.grid72),
|
||||||
|
child: BlocBuilder<TimerBloc, TimerState>(
|
||||||
|
builder: (_, state) => FloatingActionButton(
|
||||||
|
shape: state is TimerResumedState ? null : const CircleBorder(),
|
||||||
|
onPressed: () {
|
||||||
|
if (timelineAnimation.value == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final event = state is TimerStoppedState ? const StartTimerEvent() : const StopTimerEvent();
|
||||||
|
context.read<TimerBloc>().add(event);
|
||||||
|
},
|
||||||
|
child: AnimatedIcon(
|
||||||
|
icon: AnimatedIcons.play_pause,
|
||||||
|
progress: startStopIconAnimation,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in a new issue