diff options
author | Aakash Solanki <tech2aks@gmail.com> | 2022-08-31 15:23:53 +0200 |
---|---|---|
committer | Aakash Solanki <tech2aks@gmail.com> | 2022-09-14 11:50:03 +0200 |
commit | e39f2a69fde316b4e260c151757fb739494fbd56 (patch) | |
tree | 3ea8a65eee101457264d0000b5bcf122d428b0b8 /lib/screen/widgets/guages | |
parent | 5957cfa0609ff57adfafa4538fb151d00f3c72e3 (diff) |
Upload Flutter Instrument Cluster app
Instrument Cluster demo app which shows speedometer
tachometer guages, temperature and fuel bars and some
indicators like turn indicators, engine malfunction,
lights, cruise control, lane assist. KUKSA.VAL is the
data source for the widgets.
This app depends on several plugins and all the plugins
have an OSI-approved license.
Bug-AGL: SPEC-4543
Change-Id: I2698c66f9d8d824690ae7e567ca7c93ceeb17e08
Signed-off-by: Aakash Solanki <tech2aks@gmail.com>
Diffstat (limited to 'lib/screen/widgets/guages')
-rw-r--r-- | lib/screen/widgets/guages/guage_props.dart | 48 | ||||
-rw-r--r-- | lib/screen/widgets/guages/guage_widget.dart | 109 | ||||
-rw-r--r-- | lib/screen/widgets/guages/rpm_guage_animation_wrapper.dart | 51 | ||||
-rw-r--r-- | lib/screen/widgets/guages/speed_guage_animation_wrapper.dart | 66 |
4 files changed, 274 insertions, 0 deletions
diff --git a/lib/screen/widgets/guages/guage_props.dart b/lib/screen/widgets/guages/guage_props.dart new file mode 100644 index 0000000..bb56a31 --- /dev/null +++ b/lib/screen/widgets/guages/guage_props.dart @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: Apache-2.0
+
+import 'dart:math';
+import 'package:flutter/material.dart';
+
+class GuageProps {
+ static GuageColors normalModeColor = GuageColors(
+ inPrimary: const Color.fromARGB(255, 67, 67, 67),
+ outPrimary: const Color.fromARGB(255, 120, 120, 120),
+ secondary: const Color.fromARGB(156, 226, 226, 200),
+ );
+ static GuageColors sportModeColor = GuageColors(
+ inPrimary: Colors.deepPurple,
+ outPrimary: Colors.blue,
+ secondary: const Color.fromARGB(214, 202, 202, 202));
+ static GuageColors ecoModeColor = GuageColors(
+ inPrimary: const Color.fromARGB(255, 85, 165, 87),
+ outPrimary: const Color.fromARGB(255, 40, 92, 42),
+ secondary: const Color.fromARGB(202, 194, 238, 195));
+ static double majorAngle = 260;
+ static double majorAngleRad = 260 * (pi / 180);
+ static double minorAngle = 360 - majorAngle;
+ static Color bgColor = const Color.fromARGB(255, 0, 0, 0);
+ static const leftLowColor = Color(0x000000ff);
+ static const leftHighColor = Color(0x00ff0000);
+
+ static double degToRad(double deg) => deg * (pi / 180.0);
+ static TextStyle gearIconStyle(screenHeight) {
+ return TextStyle(
+ color: const Color.fromARGB(255, 84, 83, 83),
+ fontSize: (20 * screenHeight) / 480,
+ fontWeight: FontWeight.bold);
+ }
+
+ static TextStyle activeGearIconStyle(screenHeight) {
+ return TextStyle(
+ color: Colors.white,
+ fontSize: (20 * screenHeight) / 480,
+ fontWeight: FontWeight.bold);
+ }
+}
+
+class GuageColors {
+ Color? inPrimary;
+ Color? outPrimary;
+ Color? secondary;
+ GuageColors({this.inPrimary, this.outPrimary, this.secondary});
+}
diff --git a/lib/screen/widgets/guages/guage_widget.dart b/lib/screen/widgets/guages/guage_widget.dart new file mode 100644 index 0000000..fa43958 --- /dev/null +++ b/lib/screen/widgets/guages/guage_widget.dart @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: Apache-2.0
+
+import 'dart:math';
+import 'package:flutter/material.dart';
+import 'package:flutter_cluster_dashboard/screen/paints/guage_paint.dart';
+import 'package:flutter_cluster_dashboard/screen/widgets/guages/guage_props.dart';
+
+class CustomGuage extends StatelessWidget {
+ const CustomGuage({
+ Key? key,
+ required this.mainValue,
+ required this.low,
+ required this.high,
+ required this.label,
+ this.zeroTickLabel,
+ this.maxTickLabel,
+ this.distanceBWTicks,
+ this.size,
+ this.distLabelTop,
+ this.distMainTop,
+ this.distTicksBottom,
+ this.inPrimaryColor,
+ this.outPrimaryColor,
+ this.secondaryColor,
+ }) : super(key: key);
+
+ final double mainValue;
+ final double low;
+ final double high;
+ final String label;
+ final String? zeroTickLabel;
+ final String? maxTickLabel;
+ final double? distanceBWTicks;
+ final double? distTicksBottom;
+ final double? distMainTop;
+ final double? distLabelTop;
+ final double? size;
+ final Color? outPrimaryColor;
+ final Color? inPrimaryColor;
+ final Color? secondaryColor;
+
+ @override
+ Widget build(BuildContext context) {
+ TextStyle tickStyle = TextStyle(
+ color: Colors.white,
+ fontSize: ((26 / 400) * (size ?? 400)),
+ fontWeight: FontWeight.bold); //20
+ TextStyle mainValueTextStyle = TextStyle(
+ color: Colors.white,
+ fontSize: ((85 / 400) * (size ?? 400)),
+ fontWeight: FontWeight.bold); //65
+ TextStyle labelTextStyle = TextStyle(
+ color: Colors.white,
+ fontSize: ((26 / 400) * (size ?? 400)),
+ fontWeight: FontWeight.normal); //20
+ return SizedBox(
+ width: size ?? 400,
+ height: size ?? 400,
+ child: Stack(
+ alignment: Alignment.topCenter,
+ children: [
+ // Guage painter
+ Positioned(
+ top: 0,
+ child: Transform.rotate(
+ angle: (pi / 2) + (GuageProps.minorAngle * (pi / 360.0)),
+ child: CustomPaint(
+ size: Size(size ?? 400, size ?? 400),
+ painter: GuagePainter(
+ low: low,
+ high: high,
+ currentSpeed: mainValue,
+ inPrimaryColor: inPrimaryColor,
+ outPrimaryColor: outPrimaryColor,
+ secondaryColor: secondaryColor,
+ ),
+ ),
+ ),
+ ),
+ // Guage Label
+ Positioned(
+ top: distLabelTop ?? ((100 / 400) * (size ?? 400)),
+ child: Text(label, style: labelTextStyle),
+ ),
+ // Guage Main Value
+ Positioned(
+ top: distMainTop ?? ((150 / 400) * (size ?? 400)),
+ child: Text("${mainValue.toInt()}", style: mainValueTextStyle),
+ ),
+ // Guage Ticks value
+ Positioned(
+ bottom: distTicksBottom ?? ((80 / 400) * (size ?? 400)),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(zeroTickLabel ?? "", style: tickStyle),
+ SizedBox(
+ width: (size != null)
+ ? ((180 * size!) / 400)
+ : (distanceBWTicks ?? 180)),
+ Text(maxTickLabel ?? "", style: tickStyle)
+ ],
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/screen/widgets/guages/rpm_guage_animation_wrapper.dart b/lib/screen/widgets/guages/rpm_guage_animation_wrapper.dart new file mode 100644 index 0000000..95403dd --- /dev/null +++ b/lib/screen/widgets/guages/rpm_guage_animation_wrapper.dart @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: Apache-2.0
+
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:flutter_cluster_dashboard/screen/widgets/guages/guage_props.dart';
+import 'package:flutter_cluster_dashboard/screen/widgets/guages/guage_widget.dart';
+import 'package:flutter_cluster_dashboard/vehicle_signal/vehicle_signal_model.dart';
+import 'package:flutter_cluster_dashboard/vehicle_signal/vehicle_signal_provider.dart';
+
+class RPMGauge extends HookConsumerWidget {
+ final double screenHeight;
+ final GuageColors? guageColor;
+ const RPMGauge({Key? key, required this.screenHeight, this.guageColor})
+ : super(key: key);
+
+ @override
+ Widget build(BuildContext context, WidgetRef ref) {
+ final VehicleSignal vehicle = ref.watch(vehicleSignalProvider);
+
+ const double minRPM = 0;
+ const double maxRPM = 8000;
+ const Duration sweepDuration = Duration(milliseconds: 200);
+
+ final animationController = useAnimationController(
+ lowerBound: minRPM,
+ upperBound: maxRPM,
+ )..animateTo(vehicle.rpm,
+ duration: sweepDuration, curve: Curves.linearToEaseOut);
+ return AnimatedBuilder(
+ animation: animationController,
+ builder: (context, child) {
+ return Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: CustomGuage(
+ size: (248 * screenHeight) / 480,
+ low: minRPM,
+ high: maxRPM,
+ mainValue: animationController.value,
+ label: "rpm",
+ zeroTickLabel: minRPM.toInt().toString(),
+ maxTickLabel: maxRPM.toInt().toString(),
+ inPrimaryColor: guageColor?.inPrimary,
+ outPrimaryColor: guageColor?.outPrimary,
+ secondaryColor: guageColor?.secondary,
+ ),
+ );
+ });
+ }
+}
diff --git a/lib/screen/widgets/guages/speed_guage_animation_wrapper.dart b/lib/screen/widgets/guages/speed_guage_animation_wrapper.dart new file mode 100644 index 0000000..8704fcd --- /dev/null +++ b/lib/screen/widgets/guages/speed_guage_animation_wrapper.dart @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: Apache-2.0
+
+import 'package:flutter/material.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:flutter_cluster_dashboard/screen/widgets/guages/guage_props.dart';
+import 'package:flutter_cluster_dashboard/screen/widgets/guages/guage_widget.dart';
+import 'package:flutter_cluster_dashboard/vehicle_signal/vehicle_signal_model.dart';
+import 'package:flutter_cluster_dashboard/vehicle_signal/vehicle_signal_provider.dart';
+
+class SpeedGauge extends HookConsumerWidget {
+ final double screenHeight;
+ final GuageColors? guageColor;
+ const SpeedGauge({Key? key, required this.screenHeight, this.guageColor})
+ : super(key: key);
+
+ @override
+ Widget build(BuildContext context, WidgetRef ref) {
+ final VehicleSignal vehicle = ref.watch(vehicleSignalProvider);
+
+ const double minSpeed = 0;
+ const double maxSpeed = 240;
+ const Duration sweepDuration = Duration(milliseconds: 200);
+ double speedScaling =
+ (vehicle.vehicleDistanceUnit == "mi") ? 0.621504 : 1.0;
+
+ final animationController = useAnimationController(
+ lowerBound: minSpeed,
+ upperBound: maxSpeed,
+ )..animateTo(speedScaling * (vehicle.speed),
+ duration: sweepDuration, curve: Curves.linearToEaseOut);
+
+ return AnimatedBuilder(
+ animation: animationController,
+ builder: (context, child) {
+ return Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: CustomGuage(
+ size: (248 * screenHeight) / 480,
+ low: minSpeed,
+ high: maxSpeed,
+ mainValue: animationController.value,
+ label: (vehicle.vehicleDistanceUnit == "mi") ? "mph" : "Km/h",
+ zeroTickLabel: minSpeed.toInt().toString(),
+ maxTickLabel: maxSpeed.toInt().toString(),
+ inPrimaryColor: guageColor?.inPrimary,
+ outPrimaryColor: guageColor?.outPrimary,
+ secondaryColor: guageColor?.secondary,
+ ),
+ );
+ });
+ }
+}
+
+final guageColorProvider = Provider.family<GuageColors, String>((ref, mode) {
+ switch (mode) {
+ case "normal":
+ return GuageColors(inPrimary: Colors.red);
+ case "sports":
+ return GuageColors(inPrimary: Colors.blue);
+ case "eco":
+ return GuageColors(inPrimary: Colors.green);
+ default:
+ return GuageColors();
+ }
+});
|