diff options
author | Scott Murray <scott.murray@konsulko.com> | 2023-12-17 15:48:21 -0500 |
---|---|---|
committer | Jan-Simon Moeller <jsmoeller@linuxfoundation.org> | 2023-12-18 13:28:28 +0000 |
commit | 4ae68f5be11d110f2df10d54377d970921e30a21 (patch) | |
tree | b37b5cb3c6964fbaeaa95edc1edeb44d615912e9 /lib/presentation/screens/settings | |
parent | dda6c8502a3fa1e50654c4cca934b4b846bbca98 (diff) |
Implement audio settings
Changes:
- Rework KUKSA.val "VAL" gRPC API implementation to separate it
from the vehicle model + notifier, and more easily allow using
it from other notifiers.
- Move volume handling from the vehicle model + notifier to the
audio set for clarity.
- Wire up the new VSS audio signals in the audio notifier. The
"rearFront" variable naming has been changed to "fade" in
several places to match expected terminology.
- Add a balance slider to the audio settings page.
- Change the min/max labels on the fade slider to be Text instead
of Icon's since we do not have the equivalent to use with the
balance slider, and text seems like it'd be what you would want
for any potential future internationalization.
- Rework configuration file to be usable from anywhere via a
RiverPod Provider instead of tied to the vehicle notifier code,
and shifted the background and hybrid animation flags to be handled
with it. This change removes the built-in asset with defaults in
favor of maintaining the defaults for the ICS environment in the
AppConfig and KuksaConfig classes, with a goal of avoiding the need
for using async methods in the config provider.
- Change some notifiers from using StateNotifier to the RiverPod
2.0 Notifier class for improved flexibility. The other notifiers
will be updated in future work.
- Added select's to several ref.watches in the new hybrid animation
code to avoid unnecessary repaints.
- Fix several spelling issues in method and parameter names
across the codebase.
Bug-AGL: SPEC-5001
Change-Id: Iefae417fa870405d659303497d96e519e6b6d1de
Signed-off-by: Scott Murray <scott.murray@konsulko.com>
Diffstat (limited to 'lib/presentation/screens/settings')
5 files changed, 236 insertions, 83 deletions
diff --git a/lib/presentation/screens/settings/settings_screens/audio_settings/widget/audio_content.dart b/lib/presentation/screens/settings/settings_screens/audio_settings/widget/audio_content.dart index a08796d..d662272 100644 --- a/lib/presentation/screens/settings/settings_screens/audio_settings/widget/audio_content.dart +++ b/lib/presentation/screens/settings/settings_screens/audio_settings/widget/audio_content.dart @@ -16,22 +16,26 @@ class AudioContent extends ConsumerWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - CustomTrebleSlider(), + CustomBalanceSlider(), SizedBox( - height: 120, + height: 60, ), - CustomBassSlider(), + CustomFaderSlider(), + SizedBox( + height: 60, + ), + CustomTrebleSlider(), SizedBox( - height: 120, + height: 60, ), - CustomRearFrontSlider(), + CustomBassSlider(), ], ), ), Padding( padding: const EdgeInsets.only(bottom: 150), child: GenericButton( - heigth: 130, + height: 130, width: 420, text: 'Reset to Default', onTap: () { diff --git a/lib/presentation/screens/settings/settings_screens/audio_settings/widget/slider_widgets.dart b/lib/presentation/screens/settings/settings_screens/audio_settings/widget/slider_widgets.dart index 36e45e3..fefd9ed 100644 --- a/lib/presentation/screens/settings/settings_screens/audio_settings/widget/slider_widgets.dart +++ b/lib/presentation/screens/settings/settings_screens/audio_settings/widget/slider_widgets.dart @@ -1,31 +1,32 @@ import 'package:flutter_ics_homescreen/export.dart'; import 'package:flutter_ics_homescreen/presentation/custom_icons/custom_icons.dart'; -class CustomTrebleSlider extends ConsumerStatefulWidget { - const CustomTrebleSlider({ +class CustomBalanceSlider extends ConsumerStatefulWidget { + const CustomBalanceSlider({ super.key, }); @override - CustomTrebleSliderState createState() => CustomTrebleSliderState(); + CustomBalanceState createState() => CustomBalanceState(); } -class CustomTrebleSliderState extends ConsumerState<CustomTrebleSlider> { +class CustomBalanceState extends ConsumerState<CustomBalanceSlider> { bool isPressed = false; + void _increase() { setState(() { if (_currentVal < 10) { _currentVal++; - ref.read(audioStateProvider.notifier).setTreble(_currentVal); + ref.read(audioStateProvider.notifier).setBalance(_currentVal); } }); } - void _dercrease() { + void _decrease() { setState(() { if (_currentVal > 0) { _currentVal--; - ref.read(audioStateProvider.notifier).setTreble(_currentVal); + ref.read(audioStateProvider.notifier).setBalance(_currentVal); } }); } @@ -33,15 +34,15 @@ class CustomTrebleSliderState extends ConsumerState<CustomTrebleSlider> { double _currentVal = 5; @override Widget build(BuildContext context) { - final trebleValue = - ref.watch(audioStateProvider.select((audio) => audio.treble)); + final balanceValue = + ref.watch(audioStateProvider.select((audio) => audio.balance)); return Column( //crossAxisAlignment: CrossAxisAlignment.center, children: [ const Padding( padding: EdgeInsets.symmetric(vertical: 8), child: Text( - 'Treble', + 'Balance', style: TextStyle(fontSize: 40), ), ), @@ -70,15 +71,17 @@ class CustomTrebleSliderState extends ConsumerState<CustomTrebleSlider> { Padding( padding: const EdgeInsets.only(left: 40), child: InkWell( - onTap: () { - _dercrease(); - }, - child: const Icon( - Icons.remove, - color: AGLDemoColors.periwinkleColor, - size: 48, - ), - ), + onTap: () { + _decrease(); + }, + child: Text( + 'LEFT', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: AGLDemoColors.periwinkleColor, + ), + )), ), SizedBox( width: 584, @@ -86,7 +89,7 @@ class CustomTrebleSliderState extends ConsumerState<CustomTrebleSlider> { data: SliderThemeData( showValueIndicator: ShowValueIndicator.always, trackShape: CustomRoundedRectSliderTrackShape( - silderVal: trebleValue), + sliderVal: balanceValue, isFrontRear: true), activeTickMarkColor: Colors.transparent, inactiveTickMarkColor: Colors.transparent, inactiveTrackColor: AGLDemoColors.backgroundInsetColor, @@ -98,9 +101,11 @@ class CustomTrebleSliderState extends ConsumerState<CustomTrebleSlider> { divisions: 10, min: 0, max: 10, - value: trebleValue, + value: balanceValue, onChanged: (newValue) { - ref.read(audioStateProvider.notifier).setTreble(newValue); + ref + .read(audioStateProvider.notifier) + .setBalance(newValue); _currentVal = newValue; }, onChangeEnd: (value) { @@ -117,17 +122,18 @@ class CustomTrebleSliderState extends ConsumerState<CustomTrebleSlider> { ), ), Padding( - padding: const EdgeInsets.only( - right: 40, - ), + padding: const EdgeInsets.only(right: 40), child: InkWell( onTap: () { _increase(); }, - child: const Icon( - Icons.add, - color: AGLDemoColors.periwinkleColor, - size: 48, + child: Text( + 'RIGHT', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: AGLDemoColors.periwinkleColor, + ), )), ), ], @@ -138,32 +144,32 @@ class CustomTrebleSliderState extends ConsumerState<CustomTrebleSlider> { } } -class CustomBassSlider extends ConsumerStatefulWidget { - const CustomBassSlider({ +class CustomFaderSlider extends ConsumerStatefulWidget { + const CustomFaderSlider({ super.key, }); @override - CustomBassSliderState createState() => CustomBassSliderState(); + CustomFaderState createState() => CustomFaderState(); } -class CustomBassSliderState extends ConsumerState<CustomBassSlider> { +class CustomFaderState extends ConsumerState<CustomFaderSlider> { bool isPressed = false; void _increase() { setState(() { if (_currentVal < 10) { _currentVal++; - ref.read(audioStateProvider.notifier).setBass(_currentVal); + ref.read(audioStateProvider.notifier).setFade(_currentVal); } }); } - void _dercrease() { + void _decrease() { setState(() { if (_currentVal > 0) { _currentVal--; - ref.read(audioStateProvider.notifier).setBass(_currentVal); + ref.read(audioStateProvider.notifier).setFade(_currentVal); } }); } @@ -171,16 +177,15 @@ class CustomBassSliderState extends ConsumerState<CustomBassSlider> { double _currentVal = 5; @override Widget build(BuildContext context) { - final bassValue = - ref.watch(audioStateProvider.select((audio) => audio.bass)); - + final faderValue = + ref.watch(audioStateProvider.select((audio) => audio.fade)); return Column( //crossAxisAlignment: CrossAxisAlignment.center, children: [ const Padding( padding: EdgeInsets.symmetric(vertical: 8), child: Text( - 'Bass', + 'Fade', style: TextStyle(fontSize: 40), ), ), @@ -210,21 +215,24 @@ class CustomBassSliderState extends ConsumerState<CustomBassSlider> { padding: const EdgeInsets.only(left: 40), child: InkWell( onTap: () { - _dercrease(); + _decrease(); }, - child: const Icon( - Icons.remove, - color: AGLDemoColors.periwinkleColor, - size: 48, - )), + child: Text( + 'REAR', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: AGLDemoColors.periwinkleColor, + ), + )), ), SizedBox( width: 584, child: SliderTheme( data: SliderThemeData( showValueIndicator: ShowValueIndicator.always, - trackShape: - CustomRoundedRectSliderTrackShape(silderVal: bassValue), + trackShape: CustomRoundedRectSliderTrackShape( + sliderVal: faderValue, isFrontRear: true), activeTickMarkColor: Colors.transparent, inactiveTickMarkColor: Colors.transparent, inactiveTrackColor: AGLDemoColors.backgroundInsetColor, @@ -236,9 +244,11 @@ class CustomBassSliderState extends ConsumerState<CustomBassSlider> { divisions: 10, min: 0, max: 10, - value: bassValue, + value: faderValue, onChanged: (newValue) { - ref.read(audioStateProvider.notifier).setBass(newValue); + ref + .read(audioStateProvider.notifier) + .setFade(newValue); _currentVal = newValue; }, onChangeEnd: (value) { @@ -260,6 +270,146 @@ class CustomBassSliderState extends ConsumerState<CustomBassSlider> { onTap: () { _increase(); }, + child: Text( + 'FRONT', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: AGLDemoColors.periwinkleColor, + ), + )), + ), + ], + ), + ), + ], + ); + } +} + +class CustomTrebleSlider extends ConsumerStatefulWidget { + const CustomTrebleSlider({ + super.key, + }); + + @override + CustomTrebleSliderState createState() => CustomTrebleSliderState(); +} + +class CustomTrebleSliderState extends ConsumerState<CustomTrebleSlider> { + bool isPressed = false; + void _increase() { + setState(() { + if (_currentVal < 10) { + _currentVal++; + ref.read(audioStateProvider.notifier).setTreble(_currentVal); + } + }); + } + + void _decrease() { + setState(() { + if (_currentVal > 0) { + _currentVal--; + ref.read(audioStateProvider.notifier).setTreble(_currentVal); + } + }); + } + + double _currentVal = 5; + @override + Widget build(BuildContext context) { + final trebleValue = + ref.watch(audioStateProvider.select((audio) => audio.treble)); + return Column( + //crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Padding( + padding: EdgeInsets.symmetric(vertical: 8), + child: Text( + 'Treble', + style: TextStyle(fontSize: 40), + ), + ), + Container( + width: 792, + height: 160, + decoration: const ShapeDecoration( + gradient: LinearGradient( + colors: <Color>[ + AGLDemoColors.neonBlueColor, + AGLDemoColors.resolutionBlueColor, + Color.fromARGB(127, 20, 31, 100), + Color(0xFF2962FF) + ], + stops: [0, 0, 1, 1], + ), + shape: StadiumBorder( + side: BorderSide( + color: Color(0xFF5477D4), + width: 1, + )), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(left: 40), + child: InkWell( + onTap: () { + _decrease(); + }, + child: const Icon( + Icons.remove, + color: AGLDemoColors.periwinkleColor, + size: 48, + ), + ), + ), + SizedBox( + width: 584, + child: SliderTheme( + data: SliderThemeData( + showValueIndicator: ShowValueIndicator.always, + trackShape: CustomRoundedRectSliderTrackShape( + sliderVal: trebleValue), + activeTickMarkColor: Colors.transparent, + inactiveTickMarkColor: Colors.transparent, + inactiveTrackColor: AGLDemoColors.backgroundInsetColor, + thumbShape: PolygonSliderThumb( + sliderValue: 3, thumbRadius: 23, isPressed: isPressed), + trackHeight: 16, + ), + child: Slider( + divisions: 10, + min: 0, + max: 10, + value: trebleValue, + onChanged: (newValue) { + ref.read(audioStateProvider.notifier).setTreble(newValue); + _currentVal = newValue; + }, + onChangeEnd: (value) { + setState(() { + isPressed = false; + }); + }, + onChangeStart: (value) { + setState(() { + isPressed = true; + }); + }, + ), + ), + ), + Padding( + padding: const EdgeInsets.only( + right: 40, + ), + child: InkWell( + onTap: () { + _increase(); + }, child: const Icon( Icons.add, color: AGLDemoColors.periwinkleColor, @@ -274,32 +424,32 @@ class CustomBassSliderState extends ConsumerState<CustomBassSlider> { } } -class CustomRearFrontSlider extends ConsumerStatefulWidget { - const CustomRearFrontSlider({ +class CustomBassSlider extends ConsumerStatefulWidget { + const CustomBassSlider({ super.key, }); @override - CustomRearFrontState createState() => CustomRearFrontState(); + CustomBassSliderState createState() => CustomBassSliderState(); } -class CustomRearFrontState extends ConsumerState<CustomRearFrontSlider> { +class CustomBassSliderState extends ConsumerState<CustomBassSlider> { bool isPressed = false; void _increase() { setState(() { if (_currentVal < 10) { _currentVal++; - ref.read(audioStateProvider.notifier).setRearFront(_currentVal); + ref.read(audioStateProvider.notifier).setBass(_currentVal); } }); } - void _dercrease() { + void _decrease() { setState(() { if (_currentVal > 0) { _currentVal--; - ref.read(audioStateProvider.notifier).setRearFront(_currentVal); + ref.read(audioStateProvider.notifier).setBass(_currentVal); } }); } @@ -307,15 +457,16 @@ class CustomRearFrontState extends ConsumerState<CustomRearFrontSlider> { double _currentVal = 5; @override Widget build(BuildContext context) { - final rearFrontValue = - ref.watch(audioStateProvider.select((audio) => audio.rearFront)); + final bassValue = + ref.watch(audioStateProvider.select((audio) => audio.bass)); + return Column( //crossAxisAlignment: CrossAxisAlignment.center, children: [ const Padding( padding: EdgeInsets.symmetric(vertical: 8), child: Text( - 'Rear/Front', + 'Bass', style: TextStyle(fontSize: 40), ), ), @@ -345,10 +496,10 @@ class CustomRearFrontState extends ConsumerState<CustomRearFrontSlider> { padding: const EdgeInsets.only(left: 40), child: InkWell( onTap: () { - _dercrease(); + _decrease(); }, child: const Icon( - CustomIcons.slider_rear, + Icons.remove, color: AGLDemoColors.periwinkleColor, size: 48, )), @@ -358,8 +509,8 @@ class CustomRearFrontState extends ConsumerState<CustomRearFrontSlider> { child: SliderTheme( data: SliderThemeData( showValueIndicator: ShowValueIndicator.always, - trackShape: CustomRoundedRectSliderTrackShape( - silderVal: rearFrontValue, isFrontRear: true), + trackShape: + CustomRoundedRectSliderTrackShape(sliderVal: bassValue), activeTickMarkColor: Colors.transparent, inactiveTickMarkColor: Colors.transparent, inactiveTrackColor: AGLDemoColors.backgroundInsetColor, @@ -371,11 +522,9 @@ class CustomRearFrontState extends ConsumerState<CustomRearFrontSlider> { divisions: 10, min: 0, max: 10, - value: rearFrontValue, + value: bassValue, onChanged: (newValue) { - ref - .read(audioStateProvider.notifier) - .setRearFront(newValue); + ref.read(audioStateProvider.notifier).setBass(newValue); _currentVal = newValue; }, onChangeEnd: (value) { @@ -398,7 +547,7 @@ class CustomRearFrontState extends ConsumerState<CustomRearFrontSlider> { _increase(); }, child: const Icon( - CustomIcons.slider_front, + Icons.add, color: AGLDemoColors.periwinkleColor, size: 48, )), @@ -467,11 +616,11 @@ class PolygonSliderThumb extends SliderComponentShape { //TODO add border to custom track Shape class CustomRoundedRectSliderTrackShape extends SliderTrackShape with BaseSliderTrackShape { - final double silderVal; + final double sliderVal; final bool? isFrontRear; CustomRoundedRectSliderTrackShape({ - required this.silderVal, + required this.sliderVal, this.isFrontRear = false, }); @override @@ -552,10 +701,10 @@ class CustomRoundedRectSliderTrackShape extends SliderTrackShape topRight: const Radius.circular(25), bottomLeft: const Radius.circular(25), bottomRight: const Radius.circular(25)), - //silderVal > 5 ? leftTrackPaint : rightTrackPaint); + //sliderVal > 5 ? leftTrackPaint : rightTrackPaint); isFrontRear! ? rightTrackPaint - : silderVal > 5 + : sliderVal > 5 ? leftTrackPaint : rightTrackPaint); //active diff --git a/lib/presentation/screens/settings/settings_screens/bluetooth/widgets/bluetooth_content.dart b/lib/presentation/screens/settings/settings_screens/bluetooth/widgets/bluetooth_content.dart index 446a3b5..3fbb75f 100644 --- a/lib/presentation/screens/settings/settings_screens/bluetooth/widgets/bluetooth_content.dart +++ b/lib/presentation/screens/settings/settings_screens/bluetooth/widgets/bluetooth_content.dart @@ -204,7 +204,7 @@ class BluetoothContentState extends ConsumerState<BluetoothContent> { Padding( padding: const EdgeInsets.only(bottom: 150.0), child: GenericButton( - heigth: 130, + height: 130, width: 501, text: 'Scan for New Device', onTap: () {}, diff --git a/lib/presentation/screens/settings/settings_screens/profiles/widgets/new_profile_screen.dart b/lib/presentation/screens/settings/settings_screens/profiles/widgets/new_profile_screen.dart index 0cf1ddb..78b1422 100644 --- a/lib/presentation/screens/settings/settings_screens/profiles/widgets/new_profile_screen.dart +++ b/lib/presentation/screens/settings/settings_screens/profiles/widgets/new_profile_screen.dart @@ -226,7 +226,7 @@ class NewProfilePageState extends ConsumerState<NewProfilePage> { Padding( padding: const EdgeInsets.only(bottom: 350.0), child: GenericButton( - heigth: 130, + height: 130, width: 493, text: 'Save Profile', onTap: () { diff --git a/lib/presentation/screens/settings/settings_screens/profiles/widgets/profiles_content.dart b/lib/presentation/screens/settings/settings_screens/profiles/widgets/profiles_content.dart index eb89553..48e1565 100644 --- a/lib/presentation/screens/settings/settings_screens/profiles/widgets/profiles_content.dart +++ b/lib/presentation/screens/settings/settings_screens/profiles/widgets/profiles_content.dart @@ -98,7 +98,7 @@ class ProfilesContentState extends ConsumerState<ProfilesContent> { child: Column( children: [ GenericButton( - heigth: 122, + height: 122, width: 317, text: 'New Profile', onTap: () { @@ -110,7 +110,7 @@ class ProfilesContentState extends ConsumerState<ProfilesContent> { const SizedBox(height: 20), GenericButton( - heigth: 122, + height: 122, width: 412, text: 'Reset to Default', onTap: () {}, |