Enforce theme colors on switches

This commit is contained in:
Janez T
2026-03-15 10:56:47 +01:00
parent a124e3d9f2
commit 3e559a4f4e
3 changed files with 211 additions and 195 deletions

View File

@@ -774,7 +774,7 @@ class SensorMetricSelectorItem extends StatelessWidget {
), ),
), ),
), ),
Switch.adaptive(value: visible, onChanged: onToggle), Switch(value: visible, onChanged: onToggle),
], ],
), ),
const SizedBox(height: 12), const SizedBox(height: 12),

View File

@@ -1875,7 +1875,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
style: Theme.of(context).textTheme.bodySmall, style: Theme.of(context).textTheme.bodySmall,
), ),
), ),
Switch.adaptive( Switch(
value: _showCurrentImagePreview, value: _showCurrentImagePreview,
onChanged: (value) { onChanged: (value) {
setState(() => _showCurrentImagePreview = value); setState(() => _showCurrentImagePreview = value);

View File

@@ -1,123 +1,141 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
enum AppThemeMode { enum AppThemeMode { light, dark, sarRed, sarGreen, sarNavyBlue, system }
light,
dark,
sarRed,
sarGreen,
sarNavyBlue,
system,
}
class AppTheme { 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) // Light theme (Blue)
static ThemeData get lightTheme { static ThemeData get lightTheme {
return ThemeData( return _withSharedControls(
useMaterial3: true, ThemeData(
colorScheme: ColorScheme.fromSeed( useMaterial3: true,
seedColor: Colors.blue, colorScheme: ColorScheme.fromSeed(
brightness: Brightness.light, seedColor: Colors.blue,
), brightness: Brightness.light,
appBarTheme: const AppBarTheme(
centerTitle: true,
elevation: 0,
),
cardTheme: CardThemeData(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
), ),
), appBarTheme: const AppBarTheme(centerTitle: true, elevation: 0),
inputDecorationTheme: InputDecorationTheme( cardTheme: CardThemeData(
border: OutlineInputBorder( elevation: 2,
borderRadius: BorderRadius.circular(12), shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
filled: true,
), ),
filled: true,
), ),
); );
} }
// Dark theme (Blue) // Dark theme (Blue)
static ThemeData get darkTheme { static ThemeData get darkTheme {
return ThemeData( return _withSharedControls(
useMaterial3: true, ThemeData(
colorScheme: ColorScheme.fromSeed( useMaterial3: true,
seedColor: Colors.blue, colorScheme: ColorScheme.fromSeed(
brightness: Brightness.dark, seedColor: Colors.blue,
), brightness: Brightness.dark,
appBarTheme: const AppBarTheme(
centerTitle: true,
elevation: 0,
),
cardTheme: CardThemeData(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
), ),
), appBarTheme: const AppBarTheme(centerTitle: true, elevation: 0),
inputDecorationTheme: InputDecorationTheme( cardTheme: CardThemeData(
border: OutlineInputBorder( elevation: 2,
borderRadius: BorderRadius.circular(12), shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
filled: true,
), ),
filled: true,
), ),
); );
} }
// SAR Red theme (Emergency/Alert tones) // SAR Red theme (Emergency/Alert tones)
static ThemeData get sarRedTheme { static ThemeData get sarRedTheme {
return ThemeData( return _withSharedControls(
useMaterial3: true, ThemeData(
colorScheme: const ColorScheme.dark( useMaterial3: true,
brightness: Brightness.dark, colorScheme: const ColorScheme.dark(
primary: Color(0xFFFF5252), // Bright red brightness: Brightness.dark,
onPrimary: Color(0xFF000000), primary: Color(0xFFFF5252), // Bright red
primaryContainer: Color(0xFF8B0000), // Dark red onPrimary: Color(0xFF000000),
onPrimaryContainer: Color(0xFFFFCDD2), primaryContainer: Color(0xFF8B0000), // Dark red
secondary: Color(0xFFFF8A80), onPrimaryContainer: Color(0xFFFFCDD2),
onSecondary: Color(0xFF000000), secondary: Color(0xFFFF8A80),
secondaryContainer: Color(0xFFB71C1C), onSecondary: Color(0xFF000000),
onSecondaryContainer: Color(0xFFFFCDD2), secondaryContainer: Color(0xFFB71C1C),
tertiary: Color(0xFFFF6E40), onSecondaryContainer: Color(0xFFFFCDD2),
onTertiary: Color(0xFF000000), tertiary: Color(0xFFFF6E40),
error: Color(0xFFCF6679), onTertiary: Color(0xFF000000),
onError: Color(0xFF000000), error: Color(0xFFCF6679),
surface: Color(0xFF1A0000), // Very dark red-tinted onError: Color(0xFF000000),
onSurface: Color(0xFFFFEBEE), surface: Color(0xFF1A0000), // Very dark red-tinted
surfaceContainerHighest: Color(0xFF2D0000), onSurface: Color(0xFFFFEBEE),
onSurfaceVariant: Color(0xFFFFCDD2), surfaceContainerHighest: Color(0xFF2D0000),
outline: Color(0xFFFF5252), onSurfaceVariant: Color(0xFFFFCDD2),
), outline: Color(0xFFFF5252),
scaffoldBackgroundColor: const Color(0xFF1A0000), ),
appBarTheme: const AppBarTheme( scaffoldBackgroundColor: const Color(0xFF1A0000),
centerTitle: true, appBarTheme: const AppBarTheme(
elevation: 0, centerTitle: true,
backgroundColor: Color(0xFF2D0000), elevation: 0,
foregroundColor: Color(0xFFFFEBEE), backgroundColor: Color(0xFF2D0000),
), foregroundColor: Color(0xFFFFEBEE),
cardTheme: CardThemeData( ),
elevation: 2, cardTheme: CardThemeData(
color: const Color(0xFF2D0000), elevation: 2,
shape: RoundedRectangleBorder( color: const Color(0xFF2D0000),
borderRadius: BorderRadius.circular(12), shape: RoundedRectangleBorder(
side: const BorderSide( borderRadius: BorderRadius.circular(12),
color: Color(0xFFFF5252), side: const BorderSide(color: Color(0xFFFF5252), width: 1),
width: 1,
), ),
), ),
), inputDecorationTheme: InputDecorationTheme(
inputDecorationTheme: InputDecorationTheme( border: OutlineInputBorder(
border: OutlineInputBorder( borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFFFF5252)),
borderSide: const BorderSide(color: Color(0xFFFF5252)), ),
filled: true,
fillColor: const Color(0xFF2D0000),
), ),
filled: true, elevatedButtonTheme: ElevatedButtonThemeData(
fillColor: const Color(0xFF2D0000), style: ElevatedButton.styleFrom(
), backgroundColor: const Color(0xFFFF5252),
elevatedButtonTheme: ElevatedButtonThemeData( foregroundColor: const Color(0xFF000000),
style: ElevatedButton.styleFrom( ),
backgroundColor: const Color(0xFFFF5252),
foregroundColor: const Color(0xFF000000),
), ),
), ),
); );
@@ -125,58 +143,57 @@ class AppTheme {
// SAR Green theme (All Clear/Safe tones) // SAR Green theme (All Clear/Safe tones)
static ThemeData get sarGreenTheme { static ThemeData get sarGreenTheme {
return ThemeData( return _withSharedControls(
useMaterial3: true, ThemeData(
colorScheme: const ColorScheme.dark( useMaterial3: true,
brightness: Brightness.dark, colorScheme: const ColorScheme.dark(
primary: Color(0xFF69F0AE), // Bright green brightness: Brightness.dark,
onPrimary: Color(0xFF000000), primary: Color(0xFF69F0AE), // Bright green
primaryContainer: Color(0xFF00695C), // Dark teal-green onPrimary: Color(0xFF000000),
onPrimaryContainer: Color(0xFFB9F6CA), primaryContainer: Color(0xFF00695C), // Dark teal-green
secondary: Color(0xFF64FFDA), onPrimaryContainer: Color(0xFFB9F6CA),
onSecondary: Color(0xFF000000), secondary: Color(0xFF64FFDA),
secondaryContainer: Color(0xFF004D40), onSecondary: Color(0xFF000000),
onSecondaryContainer: Color(0xFFB9F6CA), secondaryContainer: Color(0xFF004D40),
tertiary: Color(0xFF1DE9B6), onSecondaryContainer: Color(0xFFB9F6CA),
onTertiary: Color(0xFF000000), tertiary: Color(0xFF1DE9B6),
error: Color(0xFFCF6679), onTertiary: Color(0xFF000000),
onError: Color(0xFF000000), error: Color(0xFFCF6679),
surface: Color(0xFF001A12), // Very dark green-tinted onError: Color(0xFF000000),
onSurface: Color(0xFFE8F5E9), surface: Color(0xFF001A12), // Very dark green-tinted
surfaceContainerHighest: Color(0xFF002D1F), onSurface: Color(0xFFE8F5E9),
onSurfaceVariant: Color(0xFFB9F6CA), surfaceContainerHighest: Color(0xFF002D1F),
outline: Color(0xFF69F0AE), onSurfaceVariant: Color(0xFFB9F6CA),
), outline: Color(0xFF69F0AE),
scaffoldBackgroundColor: const Color(0xFF001A12), ),
appBarTheme: const AppBarTheme( scaffoldBackgroundColor: const Color(0xFF001A12),
centerTitle: true, appBarTheme: const AppBarTheme(
elevation: 0, centerTitle: true,
backgroundColor: Color(0xFF002D1F), elevation: 0,
foregroundColor: Color(0xFFE8F5E9), backgroundColor: Color(0xFF002D1F),
), foregroundColor: Color(0xFFE8F5E9),
cardTheme: CardThemeData( ),
elevation: 2, cardTheme: CardThemeData(
color: const Color(0xFF002D1F), elevation: 2,
shape: RoundedRectangleBorder( color: const Color(0xFF002D1F),
borderRadius: BorderRadius.circular(12), shape: RoundedRectangleBorder(
side: const BorderSide( borderRadius: BorderRadius.circular(12),
color: Color(0xFF69F0AE), side: const BorderSide(color: Color(0xFF69F0AE), width: 1),
width: 1,
), ),
), ),
), inputDecorationTheme: InputDecorationTheme(
inputDecorationTheme: InputDecorationTheme( border: OutlineInputBorder(
border: OutlineInputBorder( borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFF69F0AE)),
borderSide: const BorderSide(color: Color(0xFF69F0AE)), ),
filled: true,
fillColor: const Color(0xFF002D1F),
), ),
filled: true, elevatedButtonTheme: ElevatedButtonThemeData(
fillColor: const Color(0xFF002D1F), style: ElevatedButton.styleFrom(
), backgroundColor: const Color(0xFF69F0AE),
elevatedButtonTheme: ElevatedButtonThemeData( foregroundColor: const Color(0xFF000000),
style: ElevatedButton.styleFrom( ),
backgroundColor: const Color(0xFF69F0AE),
foregroundColor: const Color(0xFF000000),
), ),
), ),
); );
@@ -184,58 +201,57 @@ class AppTheme {
// SAR Navy Blue theme (Professional/Operations tones) // SAR Navy Blue theme (Professional/Operations tones)
static ThemeData get sarNavyBlueTheme { static ThemeData get sarNavyBlueTheme {
return ThemeData( return _withSharedControls(
useMaterial3: true, ThemeData(
colorScheme: const ColorScheme.dark( useMaterial3: true,
brightness: Brightness.dark, colorScheme: const ColorScheme.dark(
primary: Color(0xFF5C9FFF), // Bright navy blue brightness: Brightness.dark,
onPrimary: Color(0xFF000000), primary: Color(0xFF5C9FFF), // Bright navy blue
primaryContainer: Color(0xFF003366), // Dark navy onPrimary: Color(0xFF000000),
onPrimaryContainer: Color(0xFFBBDEFF), primaryContainer: Color(0xFF003366), // Dark navy
secondary: Color(0xFF80B3FF), onPrimaryContainer: Color(0xFFBBDEFF),
onSecondary: Color(0xFF000000), secondary: Color(0xFF80B3FF),
secondaryContainer: Color(0xFF002244), onSecondary: Color(0xFF000000),
onSecondaryContainer: Color(0xFFBBDEFF), secondaryContainer: Color(0xFF002244),
tertiary: Color(0xFF4DB8FF), onSecondaryContainer: Color(0xFFBBDEFF),
onTertiary: Color(0xFF000000), tertiary: Color(0xFF4DB8FF),
error: Color(0xFFCF6679), onTertiary: Color(0xFF000000),
onError: Color(0xFF000000), error: Color(0xFFCF6679),
surface: Color(0xFF00111C), // Very dark blue-tinted onError: Color(0xFF000000),
onSurface: Color(0xFFE3F2FD), surface: Color(0xFF00111C), // Very dark blue-tinted
surfaceContainerHighest: Color(0xFF001A2D), onSurface: Color(0xFFE3F2FD),
onSurfaceVariant: Color(0xFFBBDEFF), surfaceContainerHighest: Color(0xFF001A2D),
outline: Color(0xFF5C9FFF), onSurfaceVariant: Color(0xFFBBDEFF),
), outline: Color(0xFF5C9FFF),
scaffoldBackgroundColor: const Color(0xFF00111C), ),
appBarTheme: const AppBarTheme( scaffoldBackgroundColor: const Color(0xFF00111C),
centerTitle: true, appBarTheme: const AppBarTheme(
elevation: 0, centerTitle: true,
backgroundColor: Color(0xFF001A2D), elevation: 0,
foregroundColor: Color(0xFFE3F2FD), backgroundColor: Color(0xFF001A2D),
), foregroundColor: Color(0xFFE3F2FD),
cardTheme: CardThemeData( ),
elevation: 2, cardTheme: CardThemeData(
color: const Color(0xFF001A2D), elevation: 2,
shape: RoundedRectangleBorder( color: const Color(0xFF001A2D),
borderRadius: BorderRadius.circular(12), shape: RoundedRectangleBorder(
side: const BorderSide( borderRadius: BorderRadius.circular(12),
color: Color(0xFF5C9FFF), side: const BorderSide(color: Color(0xFF5C9FFF), width: 1),
width: 1,
), ),
), ),
), inputDecorationTheme: InputDecorationTheme(
inputDecorationTheme: InputDecorationTheme( border: OutlineInputBorder(
border: OutlineInputBorder( borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFF5C9FFF)),
borderSide: const BorderSide(color: Color(0xFF5C9FFF)), ),
filled: true,
fillColor: const Color(0xFF001A2D),
), ),
filled: true, elevatedButtonTheme: ElevatedButtonThemeData(
fillColor: const Color(0xFF001A2D), style: ElevatedButton.styleFrom(
), backgroundColor: const Color(0xFF5C9FFF),
elevatedButtonTheme: ElevatedButtonThemeData( foregroundColor: const Color(0xFF000000),
style: ElevatedButton.styleFrom( ),
backgroundColor: const Color(0xFF5C9FFF),
foregroundColor: const Color(0xFF000000),
), ),
), ),
); );