diff --git a/lib/screens/metering/communication/bloc_communication_metering.dart b/lib/screens/metering/communication/bloc_communication_metering.dart index f80866c..40dcd73 100644 --- a/lib/screens/metering/communication/bloc_communication_metering.dart +++ b/lib/screens/metering/communication/bloc_communication_metering.dart @@ -8,6 +8,7 @@ class MeteringCommunicationBloc extends Bloc((_, emit) => emit(MeasureState())); + on((event, emit) => emit(EquipmentProfileChangedState(event.profile))); on((event, emit) => emit(MeteringInProgressState(event.ev100))); on((event, emit) => emit(MeteringEndedState(event.ev100))); on((_, emit) => emit(const SettingsOpenedState())); diff --git a/lib/screens/metering/communication/event_communication_metering.dart b/lib/screens/metering/communication/event_communication_metering.dart index 8872fa0..8c12656 100644 --- a/lib/screens/metering/communication/event_communication_metering.dart +++ b/lib/screens/metering/communication/event_communication_metering.dart @@ -1,19 +1,29 @@ +import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; + abstract class MeteringCommunicationEvent { const MeteringCommunicationEvent(); } -abstract class SourceEvent extends MeteringCommunicationEvent { - const SourceEvent(); -} - +/// Events sent by the screen to the current metering source. abstract class ScreenEvent extends MeteringCommunicationEvent { const ScreenEvent(); } +/// Event sent by the current metering source in response for the screen events. +abstract class SourceEvent extends MeteringCommunicationEvent { + const SourceEvent(); +} + class MeasureEvent extends ScreenEvent { const MeasureEvent(); } +class EquipmentProfileChangedEvent extends ScreenEvent { + final EquipmentProfile profile; + + const EquipmentProfileChangedEvent(this.profile); +} + abstract class MeasuredEvent extends SourceEvent { final double? ev100; diff --git a/lib/screens/metering/communication/state_communication_metering.dart b/lib/screens/metering/communication/state_communication_metering.dart index 2d3991e..1090bdc 100644 --- a/lib/screens/metering/communication/state_communication_metering.dart +++ b/lib/screens/metering/communication/state_communication_metering.dart @@ -1,3 +1,5 @@ +import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; + sealed class MeteringCommunicationState { const MeteringCommunicationState(); } @@ -18,6 +20,12 @@ class MeasureState extends SourceState { const MeasureState(); } +class EquipmentProfileChangedState extends SourceState { + final EquipmentProfile profile; + + const EquipmentProfileChangedState(this.profile); +} + sealed class MeasuredState extends ScreenState { final double? ev100; diff --git a/lib/screens/metering/components/camera_container/bloc_container_camera.dart b/lib/screens/metering/components/camera_container/bloc_container_camera.dart index 4d9bd87..76ae756 100644 --- a/lib/screens/metering/components/camera_container/bloc_container_camera.dart +++ b/lib/screens/metering/components/camera_container/bloc_container_camera.dart @@ -86,6 +86,12 @@ class CameraContainerBloc extends EvSourceBlocBase([ - if (_currentZoom != 1.0) _cameraController!.setZoomLevel(_currentZoom), - if (_currentExposureOffset != 0.0) _cameraController!.setExposureOffset(_currentExposureOffset), - ]); - - if (_zoomRange == null) { - await Future.wait([ - _cameraController!.getMinZoomLevel(), - _cameraController!.getMaxZoomLevel(), - ]).then((value) { - _zoomRange = RangeValues( - math.max(1.0, value[0]), - math.min(_maxZoom, value[1]), - ); - _currentZoom = _zoomRange!.start; - }); - } - if (_exposureOffsetRange == null) { await Future.wait([ _cameraController!.getMinExposureOffset(), @@ -173,6 +160,27 @@ class CameraContainerBloc extends EvSourceBlocBase([ + _cameraController!.getMinZoomLevel(), + _cameraController!.getMaxZoomLevel(), + ]).then((value) { + _zoomRange = RangeValues( + math.max(1.0, value[0]), + math.min(_maxZoom, value[1]), + ); + if (_currentZoom < _zoomRange!.start || _currentZoom > _zoomRange!.end) { + _currentZoom = _zoomRange!.start; + } + }); + } + + /// For app startup initialization this effectively isn't executed. + await Future.wait([ + if (_currentZoom != 1.0) _cameraController!.setZoomLevel(_currentZoom), + if (_currentExposureOffset != 0.0) _cameraController!.setExposureOffset(_currentExposureOffset), + ]); + emit(CameraInitializedState(_cameraController!)); _emitActiveState(emit); } catch (e) { @@ -187,7 +195,7 @@ class CameraContainerBloc extends EvSourceBlocBase _onZoomChanged(ZoomChangedEvent event, Emitter emit) async { - if (_cameraController != null) { + if (_cameraController != null && _zoomRange != null) { final double zoom = event.value.clamp(_zoomRange!.start, _zoomRange!.end); _cameraController!.setZoomLevel(zoom); _currentZoom = zoom; diff --git a/lib/screens/metering/components/camera_container/components/camera_controls/components/zoom_slider/widget_slider_zoom.dart b/lib/screens/metering/components/camera_container/components/camera_controls/components/zoom_slider/widget_slider_zoom.dart index 316d547..48ec91f 100644 --- a/lib/screens/metering/components/camera_container/components/camera_controls/components/zoom_slider/widget_slider_zoom.dart +++ b/lib/screens/metering/components/camera_container/components/camera_controls/components/zoom_slider/widget_slider_zoom.dart @@ -3,7 +3,7 @@ import 'package:lightmeter/providers/equipment_profile_provider.dart'; import 'package:lightmeter/screens/shared/ruler_slider/widget_slider_ruler.dart'; import 'package:lightmeter/utils/double_to_zoom.dart'; -class ZoomSlider extends StatefulWidget { +class ZoomSlider extends StatelessWidget { final RangeValues range; final double value; final ValueChanged onChanged; @@ -15,23 +15,12 @@ class ZoomSlider extends StatefulWidget { super.key, }); - @override - State createState() => _ZoomSliderState(); -} - -class _ZoomSliderState extends State { - @override - void didChangeDependencies() { - super.didChangeDependencies(); - widget.onChanged(EquipmentProfiles.selectedOf(context).lensZoom); - } - @override Widget build(BuildContext context) { return RulerSlider( - range: widget.range, - value: widget.value, - onChanged: widget.onChanged, + range: range, + value: value, + onChanged: onChanged, icon: Icons.search_outlined, defaultValue: EquipmentProfiles.selectedOf(context).lensZoom, rulerValueAdapter: (value) => value.toStringAsFixed(0), diff --git a/lib/screens/metering/components/shared/readings_container/components/equipment_profile_picker/widget_picker_equipment_profiles.dart b/lib/screens/metering/components/shared/readings_container/components/equipment_profile_picker/widget_picker_equipment_profiles.dart index 4930c46..45560e8 100644 --- a/lib/screens/metering/components/shared/readings_container/components/equipment_profile_picker/widget_picker_equipment_profiles.dart +++ b/lib/screens/metering/components/shared/readings_container/components/equipment_profile_picker/widget_picker_equipment_profiles.dart @@ -1,13 +1,28 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:lightmeter/generated/l10n.dart'; import 'package:lightmeter/providers/equipment_profile_provider.dart'; +import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart'; +import 'package:lightmeter/screens/metering/communication/event_communication_metering.dart'; import 'package:lightmeter/screens/metering/components/shared/readings_container/components/shared/animated_dialog_picker/widget_picker_dialog_animated.dart'; import 'package:lightmeter/screens/metering/components/shared/readings_container/components/shared/reading_value_container/widget_container_reading_value.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; -class EquipmentProfilePicker extends StatelessWidget { +class EquipmentProfilePicker extends StatefulWidget { const EquipmentProfilePicker(); + @override + State createState() => _EquipmentProfilePickerState(); +} + +class _EquipmentProfilePickerState extends State { + @override + void didChangeDependencies() { + super.didChangeDependencies(); + final profile = EquipmentProfiles.selectedOf(context); + context.read().add(EquipmentProfileChangedEvent(profile)); + } + @override Widget build(BuildContext context) { return AnimatedDialogPicker( @@ -16,7 +31,10 @@ class EquipmentProfilePicker extends StatelessWidget { selectedValue: EquipmentProfiles.selectedOf(context), values: EquipmentProfiles.inUseOf(context), itemTitleBuilder: (_, value) => Text(value.id.isEmpty ? S.of(context).none : value.name), - onChanged: EquipmentProfilesProvider.of(context).selectProfile, + onChanged: (profile) { + EquipmentProfilesProvider.of(context).selectProfile(profile); + context.read().add(EquipmentProfileChangedEvent(profile)); + }, closedChild: ReadingValueContainer.singleValue( value: ReadingValue( label: S.of(context).equipmentProfile,