From 4fbd3fdb9e01c197d972b78961f0d033534a5cc7 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Wed, 28 Dec 2022 15:05:26 -0500 Subject: Add volume control to bottom panel Changes: - Import a reworked version of the KUKSA.val client code from the Flutter dashboard app, with the aggregated signal Riverpod provider replaced with per-signal providers for the signal the homescreen needs and a couple of temperature ones it might use. Using separate providers is more in-line with recommended Riverpod best practices. - Various tweaks to enable using Riverpod. - Split the bottom panel out into its own widget, and add a stack in it to layer the default logo panel with the volume control slider, which has been added as a new widget definition to provide the hook to drive timer based lowering behavior like the Qt homescreen does. - The KUKSA.val connection widget has been added to the bottom panel rather than overriding the top-level widget as in the dashboard and HVAC apps. This seems preferable with respect to still providing some functionality in the event KUKSA.val is unavailable. - Remove the old demo dashboard and HVAC pages that are now unused, along with the image assets they needed, to allow cleaning up pubspec.yaml and ease maintenance. Bug-AGL: SPEC-4659 Signed-off-by: Scott Murray Change-Id: I5d9180a3461948a58321564e71134c4961ce0ef7 --- lib/page_hvac.dart | 313 ----------------------------------------------------- 1 file changed, 313 deletions(-) delete mode 100644 lib/page_hvac.dart (limited to 'lib/page_hvac.dart') diff --git a/lib/page_hvac.dart b/lib/page_hvac.dart deleted file mode 100644 index 65d77b6..0000000 --- a/lib/page_hvac.dart +++ /dev/null @@ -1,313 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_homescreen/homescreen_model.dart'; -import 'package:flutter_homescreen/layout_size_helper.dart'; -import 'package:flutter_homescreen/switchable_image.dart'; -import 'package:numberpicker/numberpicker.dart'; -import 'package:provider/provider.dart'; - -// image assets -const String LEFT_SEAT = 'images/HMI_HVAC_Left_Chair_ON.png'; -const String RIGHT_SEAT = 'images/HMI_HVAC_Right_Chair_ON.png'; -const String CIRCULATION = 'images/HMI_HVAC_Circulation_Active.png'; -const String AIRDOWN = 'images/HMI_HVAC_AirDown_Active.png'; -const String AIRUP = 'images/HMI_HVAC_AirUp_Active.png'; -const String FRONT = 'images/HMI_HVAC_Front_Active.png'; -const String REAR = 'images/HMI_HVAC_Rear_Active.png'; - -// The page for heating, ventilation, and air conditioning. -class HVACPage extends StatelessWidget { - HVACPage({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - var sizeHelper = LayoutSizeHelper(context); - - Widget fanSpeedControl = Container( - padding: EdgeInsets.symmetric( - vertical: sizeHelper.defaultPadding, - horizontal: 3.0 * sizeHelper.defaultPadding, - ), - child: Row( - children: [ - Expanded( - flex: 3, - child: HVACFanSpeed(), - ), - Expanded( - flex: 1, - child: Container( - alignment: Alignment.centerLeft, - child: Image.asset('images/HMI_HVAC_Fan_Icon.png', - width: sizeHelper.defaultIconSize, - height: sizeHelper.defaultIconSize, - fit: BoxFit.contain)), - ), - ], - - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.center, - ), - ); - - Widget centerView = Container( - padding: EdgeInsets.all(sizeHelper.defaultPadding), - child: Column( - children: [ - _HVACToggleButton( - label: 'A/C', - switchId: SwitchId.hvacAc, - ), - _HVACToggleButton( - label: 'Auto', - switchId: SwitchId.hvacAuto, - ), - _HVACToggleButton( - imageAssetId: CIRCULATION, - switchId: SwitchId.hvacCirculation, - ), - ], - ), - ); - - Widget actions = - Consumer(builder: (context, model, child) { - return Column( - children: [ - _ActionButton(switchId: SwitchId.hvacAirDown, imageAssetId: AIRDOWN), - SizedBox(height: sizeHelper.defaultPadding), - _ActionButton(switchId: SwitchId.hvacAirUp, imageAssetId: AIRUP), - SizedBox(height: sizeHelper.defaultPadding), - _ActionButton(switchId: SwitchId.hvacFront, imageAssetId: FRONT), - SizedBox(height: sizeHelper.defaultPadding), - _ActionButton(switchId: SwitchId.hvacRear, imageAssetId: REAR), - ], - ); - }); - - return Container( - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topRight, - end: Alignment.bottomLeft, - colors: [Colors.blueGrey.shade900, Colors.grey.shade900])), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - fanSpeedControl, - Row(children: [ - Expanded( - flex: 1, - child: _SeatButton( - switchId: SwitchId.hvacLeftSeat, - temperatureId: TemperatureId.leftSeat, - imageAssetId: LEFT_SEAT, - )), - Expanded(flex: 1, child: centerView), - Expanded( - flex: 1, - child: _SeatButton( - switchId: SwitchId.hvacRigthSeat, - temperatureId: TemperatureId.rightSeat, - imageAssetId: RIGHT_SEAT, - )), - Expanded(flex: 1, child: actions) - ]) - ], - )); - } -} - -// The temperature selector. -class _TemperatureSelector extends StatelessWidget { - final TemperatureId temperatureId; - - _TemperatureSelector({Key? key, required this.temperatureId}) - : super(key: key); - - @override - Widget build(BuildContext context) { - var sizeHelper = LayoutSizeHelper(context); - return Consumer( - builder: (context, model, child) { - return NumberPicker( - value: model.getTemperature(temperatureId), - minValue: 18, - maxValue: 25, - onChanged: (value) => model.setTemperature(temperatureId, value), - textStyle: DefaultTextStyle.of(context).style.copyWith( - color: Colors.teal.shade200, - fontSize: sizeHelper.baseFontSize, - ), - selectedTextStyle: DefaultTextStyle.of(context).style.copyWith( - fontSize: sizeHelper.baseFontSize * 1.5, - ), - itemHeight: sizeHelper.baseFontSize * 3, - itemWidth: sizeHelper.baseFontSize * 6, - ); - }, - ); - } -} - -/// The fan speed control. -class HVACFanSpeed extends StatelessWidget { - const HVACFanSpeed({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SliderTheme( - data: SliderThemeData( - thumbColor: Colors.greenAccent.shade700, - activeTrackColor: Colors.greenAccent.shade700, - inactiveTrackColor: Colors.blueGrey.shade200, - ), - child: Consumer( - builder: (context, model, child) { - return Slider( - value: model.fanSpeed, - min: 0, - max: 300, - label: model.fanSpeed.round().toString(), - onChanged: (double newValue) { - model.fanSpeed = newValue; - }, - ); - }, - ), - ); - } -} - -// the button to enable A/C on each seat -class _SeatButton extends StatelessWidget { - final SwitchId switchId; - final TemperatureId temperatureId; - final String imageAssetId; - - const _SeatButton({ - Key? key, - required this.switchId, - required this.temperatureId, - required this.imageAssetId, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - var sizeHelper = LayoutSizeHelper(context); - return Container( - padding: EdgeInsets.all(sizeHelper.defaultPadding), - child: Column( - children: [ - Consumer( - builder: (context, model, child) { - return IconButton( - onPressed: () => model.flipSwitch(switchId), - iconSize: sizeHelper.largeIconSize, - icon: SwitchableImage( - value: model.getSwitchState(switchId), - imageAssetId: imageAssetId, - width: sizeHelper.largeIconSize, - height: sizeHelper.largeIconSize, - ), - ); - }, - ), - SizedBox(height: sizeHelper.defaultPadding), - _TemperatureSelector(temperatureId: temperatureId), - ], - ), - ); - } -} - -// Each one of the large toggle buttons in the UI. -class _HVACToggleButton extends StatelessWidget { - final String? label; - final String? imageAssetId; - final SwitchId switchId; - - _HVACToggleButton( - {Key? key, required this.switchId, this.label, this.imageAssetId}) - : super(key: key); - - @override - Widget build(BuildContext context) { - var sizeHelper = LayoutSizeHelper(context); - TextStyle buttonTextStyle = DefaultTextStyle.of(context).style.copyWith( - fontSize: sizeHelper.baseFontSize, - fontWeight: FontWeight.bold, - ); - TextStyle unselectedButtonTextStyle = buttonTextStyle.copyWith( - color: Colors.grey, - fontWeight: FontWeight.normal, - ); - - return Container( - width: sizeHelper.defaultButtonWidth, - height: sizeHelper.defaultButtonHeight, - margin: EdgeInsets.all(sizeHelper.defaultPadding), - child: Consumer( - builder: (context, model, child) { - return OutlinedButton( - onPressed: () => model.flipSwitch(switchId), - style: OutlinedButton.styleFrom( - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(sizeHelper.defaultButtonHeight / 4.0), - ), - side: BorderSide( - width: sizeHelper.defaultBorder, - color: - model.getSwitchState(switchId) ? Colors.green : Colors.grey, - style: BorderStyle.solid, - ), - ), - child: (imageAssetId != null) - ? SwitchableImage( - value: model.getSwitchState(switchId), - imageAssetId: imageAssetId ?? '', - width: sizeHelper.defaultIconSize, - height: sizeHelper.defaultIconSize, - ) - : Text( - label ?? '', - style: model.getSwitchState(switchId) - ? buttonTextStyle - : unselectedButtonTextStyle, - ), - ); - }, - ), - ); - } -} - -// Each one of the small action buttons. -class _ActionButton extends StatelessWidget { - final SwitchId switchId; - final String imageAssetId; - - const _ActionButton( - {Key? key, required this.switchId, required this.imageAssetId}) - : super(key: key); - - @override - Widget build(BuildContext context) { - var sizeHelper = LayoutSizeHelper(context); - return Consumer( - builder: (context, model, child) { - return IconButton( - onPressed: () => model.flipSwitch(switchId), - iconSize: sizeHelper.defaultIconSize, - icon: SwitchableImage( - value: model.getSwitchState(switchId), - imageAssetId: imageAssetId, - width: sizeHelper.defaultIconSize, - height: sizeHelper.defaultIconSize, - ), - ); - }, - ); - } -} -- cgit 1.2.3-korg