From 3e559a4f4e29aeeb9b0a65bff8192442fc7a4a17 Mon Sep 17 00:00:00 2001 From: Janez T Date: Sun, 15 Mar 2026 10:56:47 +0100 Subject: [PATCH] Enforce theme colors on switches --- lib/screens/sensors_tab.dart | 2 +- lib/screens/settings_screen.dart | 2 +- lib/theme/app_theme.dart | 402 ++++++++++++++++--------------- 3 files changed, 211 insertions(+), 195 deletions(-) diff --git a/lib/screens/sensors_tab.dart b/lib/screens/sensors_tab.dart index 0e59edd..2396035 100644 --- a/lib/screens/sensors_tab.dart +++ b/lib/screens/sensors_tab.dart @@ -774,7 +774,7 @@ class SensorMetricSelectorItem extends StatelessWidget { ), ), ), - Switch.adaptive(value: visible, onChanged: onToggle), + Switch(value: visible, onChanged: onToggle), ], ), const SizedBox(height: 12), diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index e690dd0..cbb3fd2 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -1875,7 +1875,7 @@ class _SettingsScreenState extends State { style: Theme.of(context).textTheme.bodySmall, ), ), - Switch.adaptive( + Switch( value: _showCurrentImagePreview, onChanged: (value) { setState(() => _showCurrentImagePreview = value); diff --git a/lib/theme/app_theme.dart b/lib/theme/app_theme.dart index d942e93..b63b1cf 100644 --- a/lib/theme/app_theme.dart +++ b/lib/theme/app_theme.dart @@ -1,123 +1,141 @@ import 'package:flutter/material.dart'; -enum AppThemeMode { - light, - dark, - sarRed, - sarGreen, - sarNavyBlue, - system, -} +enum AppThemeMode { light, dark, sarRed, sarGreen, sarNavyBlue, system } class AppTheme { + static ThemeData _withSharedControls(ThemeData theme) { + final colorScheme = theme.colorScheme; + return theme.copyWith( + switchTheme: SwitchThemeData( + thumbColor: WidgetStateProperty.resolveWith((states) { + if (states.contains(WidgetState.disabled)) { + return colorScheme.onSurface.withValues(alpha: 0.38); + } + if (states.contains(WidgetState.selected)) { + return colorScheme.onPrimary; + } + return colorScheme.outline; + }), + trackColor: WidgetStateProperty.resolveWith((states) { + if (states.contains(WidgetState.disabled)) { + return colorScheme.onSurface.withValues(alpha: 0.12); + } + if (states.contains(WidgetState.selected)) { + return colorScheme.primary; + } + return colorScheme.surfaceContainerHighest; + }), + trackOutlineColor: WidgetStateProperty.resolveWith((states) { + if (states.contains(WidgetState.selected)) { + return colorScheme.primary; + } + return colorScheme.outlineVariant; + }), + ), + ); + } + // Light theme (Blue) static ThemeData get lightTheme { - return ThemeData( - useMaterial3: true, - colorScheme: ColorScheme.fromSeed( - seedColor: Colors.blue, - brightness: Brightness.light, - ), - appBarTheme: const AppBarTheme( - centerTitle: true, - elevation: 0, - ), - cardTheme: CardThemeData( - elevation: 2, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + return _withSharedControls( + ThemeData( + useMaterial3: true, + colorScheme: ColorScheme.fromSeed( + seedColor: Colors.blue, + brightness: Brightness.light, ), - ), - inputDecorationTheme: InputDecorationTheme( - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), + appBarTheme: const AppBarTheme(centerTitle: true, elevation: 0), + cardTheme: CardThemeData( + elevation: 2, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + inputDecorationTheme: InputDecorationTheme( + border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)), + filled: true, ), - filled: true, ), ); } // Dark theme (Blue) static ThemeData get darkTheme { - return ThemeData( - useMaterial3: true, - colorScheme: ColorScheme.fromSeed( - seedColor: Colors.blue, - brightness: Brightness.dark, - ), - appBarTheme: const AppBarTheme( - centerTitle: true, - elevation: 0, - ), - cardTheme: CardThemeData( - elevation: 2, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + return _withSharedControls( + ThemeData( + useMaterial3: true, + colorScheme: ColorScheme.fromSeed( + seedColor: Colors.blue, + brightness: Brightness.dark, ), - ), - inputDecorationTheme: InputDecorationTheme( - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), + appBarTheme: const AppBarTheme(centerTitle: true, elevation: 0), + cardTheme: CardThemeData( + elevation: 2, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + inputDecorationTheme: InputDecorationTheme( + border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)), + filled: true, ), - filled: true, ), ); } // SAR Red theme (Emergency/Alert tones) static ThemeData get sarRedTheme { - return ThemeData( - useMaterial3: true, - colorScheme: const ColorScheme.dark( - brightness: Brightness.dark, - primary: Color(0xFFFF5252), // Bright red - onPrimary: Color(0xFF000000), - primaryContainer: Color(0xFF8B0000), // Dark red - onPrimaryContainer: Color(0xFFFFCDD2), - secondary: Color(0xFFFF8A80), - onSecondary: Color(0xFF000000), - secondaryContainer: Color(0xFFB71C1C), - onSecondaryContainer: Color(0xFFFFCDD2), - tertiary: Color(0xFFFF6E40), - onTertiary: Color(0xFF000000), - error: Color(0xFFCF6679), - onError: Color(0xFF000000), - surface: Color(0xFF1A0000), // Very dark red-tinted - onSurface: Color(0xFFFFEBEE), - surfaceContainerHighest: Color(0xFF2D0000), - onSurfaceVariant: Color(0xFFFFCDD2), - outline: Color(0xFFFF5252), - ), - scaffoldBackgroundColor: const Color(0xFF1A0000), - appBarTheme: const AppBarTheme( - centerTitle: true, - elevation: 0, - backgroundColor: Color(0xFF2D0000), - foregroundColor: Color(0xFFFFEBEE), - ), - cardTheme: CardThemeData( - elevation: 2, - color: const Color(0xFF2D0000), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), - side: const BorderSide( - color: Color(0xFFFF5252), - width: 1, + return _withSharedControls( + ThemeData( + useMaterial3: true, + colorScheme: const ColorScheme.dark( + brightness: Brightness.dark, + primary: Color(0xFFFF5252), // Bright red + onPrimary: Color(0xFF000000), + primaryContainer: Color(0xFF8B0000), // Dark red + onPrimaryContainer: Color(0xFFFFCDD2), + secondary: Color(0xFFFF8A80), + onSecondary: Color(0xFF000000), + secondaryContainer: Color(0xFFB71C1C), + onSecondaryContainer: Color(0xFFFFCDD2), + tertiary: Color(0xFFFF6E40), + onTertiary: Color(0xFF000000), + error: Color(0xFFCF6679), + onError: Color(0xFF000000), + surface: Color(0xFF1A0000), // Very dark red-tinted + onSurface: Color(0xFFFFEBEE), + surfaceContainerHighest: Color(0xFF2D0000), + onSurfaceVariant: Color(0xFFFFCDD2), + outline: Color(0xFFFF5252), + ), + scaffoldBackgroundColor: const Color(0xFF1A0000), + appBarTheme: const AppBarTheme( + centerTitle: true, + elevation: 0, + backgroundColor: Color(0xFF2D0000), + foregroundColor: Color(0xFFFFEBEE), + ), + cardTheme: CardThemeData( + elevation: 2, + color: const Color(0xFF2D0000), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: const BorderSide(color: Color(0xFFFF5252), width: 1), ), ), - ), - inputDecorationTheme: InputDecorationTheme( - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), - borderSide: const BorderSide(color: Color(0xFFFF5252)), + inputDecorationTheme: InputDecorationTheme( + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: const BorderSide(color: Color(0xFFFF5252)), + ), + filled: true, + fillColor: const Color(0xFF2D0000), ), - filled: true, - fillColor: const Color(0xFF2D0000), - ), - elevatedButtonTheme: ElevatedButtonThemeData( - style: ElevatedButton.styleFrom( - backgroundColor: const Color(0xFFFF5252), - foregroundColor: const Color(0xFF000000), + elevatedButtonTheme: ElevatedButtonThemeData( + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFFFF5252), + foregroundColor: const Color(0xFF000000), + ), ), ), ); @@ -125,58 +143,57 @@ class AppTheme { // SAR Green theme (All Clear/Safe tones) static ThemeData get sarGreenTheme { - return ThemeData( - useMaterial3: true, - colorScheme: const ColorScheme.dark( - brightness: Brightness.dark, - primary: Color(0xFF69F0AE), // Bright green - onPrimary: Color(0xFF000000), - primaryContainer: Color(0xFF00695C), // Dark teal-green - onPrimaryContainer: Color(0xFFB9F6CA), - secondary: Color(0xFF64FFDA), - onSecondary: Color(0xFF000000), - secondaryContainer: Color(0xFF004D40), - onSecondaryContainer: Color(0xFFB9F6CA), - tertiary: Color(0xFF1DE9B6), - onTertiary: Color(0xFF000000), - error: Color(0xFFCF6679), - onError: Color(0xFF000000), - surface: Color(0xFF001A12), // Very dark green-tinted - onSurface: Color(0xFFE8F5E9), - surfaceContainerHighest: Color(0xFF002D1F), - onSurfaceVariant: Color(0xFFB9F6CA), - outline: Color(0xFF69F0AE), - ), - scaffoldBackgroundColor: const Color(0xFF001A12), - appBarTheme: const AppBarTheme( - centerTitle: true, - elevation: 0, - backgroundColor: Color(0xFF002D1F), - foregroundColor: Color(0xFFE8F5E9), - ), - cardTheme: CardThemeData( - elevation: 2, - color: const Color(0xFF002D1F), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), - side: const BorderSide( - color: Color(0xFF69F0AE), - width: 1, + return _withSharedControls( + ThemeData( + useMaterial3: true, + colorScheme: const ColorScheme.dark( + brightness: Brightness.dark, + primary: Color(0xFF69F0AE), // Bright green + onPrimary: Color(0xFF000000), + primaryContainer: Color(0xFF00695C), // Dark teal-green + onPrimaryContainer: Color(0xFFB9F6CA), + secondary: Color(0xFF64FFDA), + onSecondary: Color(0xFF000000), + secondaryContainer: Color(0xFF004D40), + onSecondaryContainer: Color(0xFFB9F6CA), + tertiary: Color(0xFF1DE9B6), + onTertiary: Color(0xFF000000), + error: Color(0xFFCF6679), + onError: Color(0xFF000000), + surface: Color(0xFF001A12), // Very dark green-tinted + onSurface: Color(0xFFE8F5E9), + surfaceContainerHighest: Color(0xFF002D1F), + onSurfaceVariant: Color(0xFFB9F6CA), + outline: Color(0xFF69F0AE), + ), + scaffoldBackgroundColor: const Color(0xFF001A12), + appBarTheme: const AppBarTheme( + centerTitle: true, + elevation: 0, + backgroundColor: Color(0xFF002D1F), + foregroundColor: Color(0xFFE8F5E9), + ), + cardTheme: CardThemeData( + elevation: 2, + color: const Color(0xFF002D1F), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: const BorderSide(color: Color(0xFF69F0AE), width: 1), ), ), - ), - inputDecorationTheme: InputDecorationTheme( - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), - borderSide: const BorderSide(color: Color(0xFF69F0AE)), + inputDecorationTheme: InputDecorationTheme( + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: const BorderSide(color: Color(0xFF69F0AE)), + ), + filled: true, + fillColor: const Color(0xFF002D1F), ), - filled: true, - fillColor: const Color(0xFF002D1F), - ), - elevatedButtonTheme: ElevatedButtonThemeData( - style: ElevatedButton.styleFrom( - backgroundColor: const Color(0xFF69F0AE), - foregroundColor: const Color(0xFF000000), + elevatedButtonTheme: ElevatedButtonThemeData( + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF69F0AE), + foregroundColor: const Color(0xFF000000), + ), ), ), ); @@ -184,58 +201,57 @@ class AppTheme { // SAR Navy Blue theme (Professional/Operations tones) static ThemeData get sarNavyBlueTheme { - return ThemeData( - useMaterial3: true, - colorScheme: const ColorScheme.dark( - brightness: Brightness.dark, - primary: Color(0xFF5C9FFF), // Bright navy blue - onPrimary: Color(0xFF000000), - primaryContainer: Color(0xFF003366), // Dark navy - onPrimaryContainer: Color(0xFFBBDEFF), - secondary: Color(0xFF80B3FF), - onSecondary: Color(0xFF000000), - secondaryContainer: Color(0xFF002244), - onSecondaryContainer: Color(0xFFBBDEFF), - tertiary: Color(0xFF4DB8FF), - onTertiary: Color(0xFF000000), - error: Color(0xFFCF6679), - onError: Color(0xFF000000), - surface: Color(0xFF00111C), // Very dark blue-tinted - onSurface: Color(0xFFE3F2FD), - surfaceContainerHighest: Color(0xFF001A2D), - onSurfaceVariant: Color(0xFFBBDEFF), - outline: Color(0xFF5C9FFF), - ), - scaffoldBackgroundColor: const Color(0xFF00111C), - appBarTheme: const AppBarTheme( - centerTitle: true, - elevation: 0, - backgroundColor: Color(0xFF001A2D), - foregroundColor: Color(0xFFE3F2FD), - ), - cardTheme: CardThemeData( - elevation: 2, - color: const Color(0xFF001A2D), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), - side: const BorderSide( - color: Color(0xFF5C9FFF), - width: 1, + return _withSharedControls( + ThemeData( + useMaterial3: true, + colorScheme: const ColorScheme.dark( + brightness: Brightness.dark, + primary: Color(0xFF5C9FFF), // Bright navy blue + onPrimary: Color(0xFF000000), + primaryContainer: Color(0xFF003366), // Dark navy + onPrimaryContainer: Color(0xFFBBDEFF), + secondary: Color(0xFF80B3FF), + onSecondary: Color(0xFF000000), + secondaryContainer: Color(0xFF002244), + onSecondaryContainer: Color(0xFFBBDEFF), + tertiary: Color(0xFF4DB8FF), + onTertiary: Color(0xFF000000), + error: Color(0xFFCF6679), + onError: Color(0xFF000000), + surface: Color(0xFF00111C), // Very dark blue-tinted + onSurface: Color(0xFFE3F2FD), + surfaceContainerHighest: Color(0xFF001A2D), + onSurfaceVariant: Color(0xFFBBDEFF), + outline: Color(0xFF5C9FFF), + ), + scaffoldBackgroundColor: const Color(0xFF00111C), + appBarTheme: const AppBarTheme( + centerTitle: true, + elevation: 0, + backgroundColor: Color(0xFF001A2D), + foregroundColor: Color(0xFFE3F2FD), + ), + cardTheme: CardThemeData( + elevation: 2, + color: const Color(0xFF001A2D), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: const BorderSide(color: Color(0xFF5C9FFF), width: 1), ), ), - ), - inputDecorationTheme: InputDecorationTheme( - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), - borderSide: const BorderSide(color: Color(0xFF5C9FFF)), + inputDecorationTheme: InputDecorationTheme( + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: const BorderSide(color: Color(0xFF5C9FFF)), + ), + filled: true, + fillColor: const Color(0xFF001A2D), ), - filled: true, - fillColor: const Color(0xFF001A2D), - ), - elevatedButtonTheme: ElevatedButtonThemeData( - style: ElevatedButton.styleFrom( - backgroundColor: const Color(0xFF5C9FFF), - foregroundColor: const Color(0xFF000000), + elevatedButtonTheme: ElevatedButtonThemeData( + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF5C9FFF), + foregroundColor: const Color(0xFF000000), + ), ), ), );