diff --git a/lib/application.dart b/lib/application.dart index ed596a5..79055d5 100644 --- a/lib/application.dart +++ b/lib/application.dart @@ -18,6 +18,7 @@ import 'environment.dart'; import 'generated/l10n.dart'; import 'providers/equipment_profile_provider.dart'; import 'providers/ev_source_type_provider.dart'; +import 'providers/features_provider.dart'; import 'providers/theme_provider.dart'; import 'screens/metering/flow_metering.dart'; import 'screens/settings/flow_settings.dart'; @@ -47,31 +48,33 @@ class Application extends StatelessWidget { Provider(create: (_) => PermissionsService()), Provider(create: (_) => const LightSensorService()), ], - child: StopTypeProvider( - child: EquipmentProfileProvider( - child: EvSourceTypeProvider( - child: SupportedLocaleProvider( - child: ThemeProvider( - builder: (context, _) => _AnnotatedRegionWrapper( - child: MaterialApp( - theme: context.watch(), - locale: Locale(context.watch().intlName), - localizationsDelegates: const [ - S.delegate, - GlobalMaterialLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - GlobalCupertinoLocalizations.delegate, - ], - supportedLocales: S.delegate.supportedLocales, - builder: (context, child) => MediaQuery( - data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0), - child: child!, + child: MeteringScreenLayoutProvider( + child: StopTypeProvider( + child: EquipmentProfileProvider( + child: EvSourceTypeProvider( + child: SupportedLocaleProvider( + child: ThemeProvider( + builder: (context, _) => _AnnotatedRegionWrapper( + child: MaterialApp( + theme: context.watch(), + locale: Locale(context.watch().intlName), + localizationsDelegates: const [ + S.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: S.delegate.supportedLocales, + builder: (context, child) => MediaQuery( + data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0), + child: child!, + ), + initialRoute: "metering", + routes: { + "metering": (context) => const MeteringFlow(), + "settings": (context) => const SettingsFlow(), + }, ), - initialRoute: "metering", - routes: { - "metering": (context) => const MeteringFlow(), - "settings": (context) => const SettingsFlow(), - }, ), ), ), diff --git a/lib/providers/features_provider.dart b/lib/providers/features_provider.dart new file mode 100644 index 0000000..319063e --- /dev/null +++ b/lib/providers/features_provider.dart @@ -0,0 +1,75 @@ +import 'package:flutter/material.dart'; + +enum MeteringScreenLayoutFeature { extremeExposurePairs, reciprocity } + +class MeteringScreenLayoutProvider extends StatefulWidget { + final Widget child; + + const MeteringScreenLayoutProvider({required this.child, super.key}); + + static MeteringScreenLayoutProviderState of(BuildContext context) { + return context.findAncestorStateOfType()!; + } + + @override + State createState() => MeteringScreenLayoutProviderState(); +} + +class MeteringScreenLayoutProviderState extends State { + final Map _features = { + MeteringScreenLayoutFeature.extremeExposurePairs: true, + MeteringScreenLayoutFeature.reciprocity: true, + }; + + @override + Widget build(BuildContext context) { + return MeteringScreenLayout( + features: _features, + child: widget.child, + ); + } + + void setFeature(MeteringScreenLayoutFeature feature, {required bool enabled}) { + setState(() { + _features.update( + feature, + (_) => enabled, + ifAbsent: () => enabled, + ); + }); + } +} + +class MeteringScreenLayout extends InheritedModel { + final Map features; + + const MeteringScreenLayout({ + required this.features, + required super.child, + super.key, + }); + + static bool of(BuildContext context, MeteringScreenLayoutFeature feature, {bool listen = true}) { + if (listen) { + return context.dependOnInheritedWidgetOfExactType()!.features[feature]!; + } else { + return context.findAncestorWidgetOfExactType()!.features[feature]!; + } + } + + @override + bool updateShouldNotify(MeteringScreenLayout oldWidget) => true; + + @override + bool updateShouldNotifyDependent( + MeteringScreenLayout oldWidget, + Set dependencies, + ) { + for (final dependecy in dependencies) { + if (oldWidget.features[dependecy] != features[dependecy]) { + return true; + } + } + return false; + } +}