import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; /// 主题模式枚举 enum ThemeModeType { system, // 跟随系统 light, // 浅色模式 dark, // 深色模式 } /// 主题配置提供者 final themeModeProvider = StateNotifierProvider( (ref) => ThemeModeNotifier(), ); /// 主题模式状态管理器 class ThemeModeNotifier extends StateNotifier { ThemeModeNotifier() : super(ThemeModeType.system); /// 设置主题模式 void setThemeMode(ThemeModeType mode) { state = mode; } /// 切换深色/浅色模式 void toggleDarkMode() { state = state == ThemeModeType.dark ? ThemeModeType.light : ThemeModeType.dark; } /// 获取对应的 Flutter ThemeMode ThemeMode get flutterThemeMode { switch (state) { case ThemeModeType.system: return ThemeMode.system; case ThemeModeType.light: return ThemeMode.light; case ThemeModeType.dark: return ThemeMode.dark; } } /// 判断是否为深色模式 bool get isDarkMode { return state == ThemeModeType.dark; } } /// EDA 专用主题配置 class EdaTheme { // ========== 浅色主题配色 ========== // 主色调 - EDA 行业常用蓝色系 static const Color lightPrimaryColor = Color(0xFF1976D2); static const Color lightSecondaryColor = Color(0xFF42A5F5); static const Color lightAccentColor = Color(0xFFFF9800); // 背景色 static const Color lightScaffoldBg = Color(0xFFF5F5F5); static const Color lightCanvasBg = Color(0xFFFAFAFA); static const Color lightCardBg = Color(0xFFFFFFFF); static const Color lightSurfaceBg = Color(0xFFFFFFFF); // 网格颜色 static const Color lightGridColor = Color(0xFFE0E0E0); static const Color lightGridDotColor = Color(0xFFBDBDBD); // 元件颜色 static const Color lightComponentColor = Color(0xFF212121); static const Color lightComponentBg = Color(0xFFFFFFFF); static const Color lightPinColor = Color(0xFF424242); static const Color lightWireColor = Color(0xFF1976D2); // 选中/高亮颜色 static const Color lightSelectedColor = Color(0xFFFF9800); static const Color lightHighlightColor = Color(0xFF4CAF50); static const Color lightHoverColor = Color(0xFFE3F2FD); // 文本颜色 static const Color lightTextPrimary = Color(0xFF212121); static const Color lightTextSecondary = Color(0xFF757575); static const Color lightTextHint = Color(0xFFBDBDBD); // 边框/分割线颜色 static const Color lightBorderColor = Color(0xFFE0E0E0); static const Color lightDividerColor = Color(0xFFEEEEEE); // ========== 深色主题配色 ========== // 主色调 - 保持品牌一致性,稍微降低饱和度 static const Color darkPrimaryColor = Color(0xFF42A5F5); static const Color darkSecondaryColor = Color(0xFF64B5F6); static const Color darkAccentColor = Color(0xFFFFB74D); // 背景色 - 遵循 Material Design 深色主题规范 static const Color darkScaffoldBg = Color(0xFF121212); static const Color darkCanvasBg = Color(0xFF1E1E1E); static const Color darkCardBg = Color(0xFF1E1E1E); static const Color darkSurfaceBg = Color(0xFF2D2D2D); // 网格颜色 - 降低对比度避免视觉疲劳 static const Color darkGridColor = Color(0xFF333333); static const Color darkGridDotColor = Color(0xFF424242); // 元件颜色 - 提高亮度确保可见性 static const Color darkComponentColor = Color(0xFFE0E0E0); static const Color darkComponentBg = Color(0xFF2D2D2D); static const Color darkPinColor = Color(0xFFBDBDBD); static const Color darkWireColor = Color(0xFF64B5F6); // 选中/高亮颜色 - 提高饱和度 static const Color darkSelectedColor = Color(0xFFFFB74D); static const Color darkHighlightColor = Color(0xFF81C784); static const Color darkHoverColor = Color(0xFF424242); // 文本颜色 - 遵循 Material Design 深色主题文本规范 static const Color darkTextPrimary = Color(0xFFE0E0E0); static const Color darkTextSecondary = Color(0xFFB0B0B0); static const Color darkTextHint = Color(0xFF757575); // 边框/分割线颜色 static const Color darkBorderColor = Color(0xFF424242); static const Color darkDividerColor = Color(0xFF333333); /// 获取浅色主题 static ThemeData get lightTheme { return ThemeData( useMaterial3: true, brightness: Brightness.light, colorScheme: const ColorScheme.light( primary: lightPrimaryColor, secondary: lightSecondaryColor, tertiary: lightAccentColor, surface: lightSurfaceBg, error: Color(0xFFB00020), onPrimary: Colors.white, onSecondary: Colors.white, onSurface: lightTextPrimary, onError: Colors.white, ), scaffoldBackgroundColor: lightScaffoldBg, canvasColor: lightCanvasBg, cardColor: lightCardBg, dividerColor: lightDividerColor, // AppBar 主题 appBarTheme: const AppBarTheme( backgroundColor: lightPrimaryColor, foregroundColor: Colors.white, elevation: 2, centerTitle: false, titleTextStyle: TextStyle( color: Colors.white, fontSize: 20, fontWeight: FontWeight.w600, ), ), // 卡片主题 cardTheme: CardTheme( color: lightCardBg, elevation: 2, shadowColor: Colors.black12, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), // 按钮主题 elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: lightPrimaryColor, foregroundColor: Colors.white, elevation: 2, padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), ), // 文本字段主题 inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: lightCardBg, border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: lightBorderColor), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: lightBorderColor), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: lightPrimaryColor, width: 2), ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: Color(0xFFB00020)), ), contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), ), // 文本主题 textTheme: const TextTheme( displayLarge: TextStyle(color: lightTextPrimary, fontSize: 32, fontWeight: FontWeight.bold), displayMedium: TextStyle(color: lightTextPrimary, fontSize: 28, fontWeight: FontWeight.bold), displaySmall: TextStyle(color: lightTextPrimary, fontSize: 24, fontWeight: FontWeight.bold), headlineLarge: TextStyle(color: lightTextPrimary, fontSize: 22, fontWeight: FontWeight.w600), headlineMedium: TextStyle(color: lightTextPrimary, fontSize: 20, fontWeight: FontWeight.w600), headlineSmall: TextStyle(color: lightTextPrimary, fontSize: 18, fontWeight: FontWeight.w600), titleLarge: TextStyle(color: lightTextPrimary, fontSize: 16, fontWeight: FontWeight.w600), titleMedium: TextStyle(color: lightTextPrimary, fontSize: 14, fontWeight: FontWeight.w500), titleSmall: TextStyle(color: lightTextPrimary, fontSize: 12, fontWeight: FontWeight.w500), bodyLarge: TextStyle(color: lightTextPrimary, fontSize: 16), bodyMedium: TextStyle(color: lightTextPrimary, fontSize: 14), bodySmall: TextStyle(color: lightTextSecondary, fontSize: 12), labelLarge: TextStyle(color: lightTextPrimary, fontSize: 14, fontWeight: FontWeight.w500), labelMedium: TextStyle(color: lightTextSecondary, fontSize: 12), labelSmall: TextStyle(color: lightTextHint, fontSize: 10), ), // 图标主题 iconTheme: const IconThemeData( color: lightTextPrimary, size: 24, ), // 开关主题 switchTheme: SwitchThemeData( thumbColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.selected)) { return lightPrimaryColor; } return Colors.grey; }), trackColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.selected)) { return lightPrimaryColor.withOpacity(0.5); } return Colors.grey.shade300; }), ), // 复选框主题 checkboxTheme: CheckboxThemeData( fillColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.selected)) { return lightPrimaryColor; } return Colors.transparent; }), ), // 单选按钮主题 radioTheme: RadioThemeData( fillColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.selected)) { return lightPrimaryColor; } return Colors.grey; }), ), // 滑块主题 sliderTheme: SliderThemeData( activeTrackColor: lightPrimaryColor, inactiveTrackColor: lightPrimaryColor.withOpacity(0.3), thumbColor: lightPrimaryColor, overlayColor: lightPrimaryColor.withOpacity(0.12), ), // 底部导航栏主题 bottomNavigationBarTheme: const BottomNavigationBarThemeData( backgroundColor: lightCardBg, selectedItemColor: lightPrimaryColor, unselectedItemColor: lightTextSecondary, type: BottomNavigationBarType.fixed, elevation: 8, ), // 导航抽屉主题 drawerTheme: const DrawerThemeData( backgroundColor: lightCardBg, ), // 对话框主题 dialogTheme: DialogTheme( backgroundColor: lightCardBg, elevation: 8, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), ), // 底部工作表主题 bottomSheetTheme: const BottomSheetThemeData( backgroundColor: lightCardBg, elevation: 8, shape: RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(16)), ), ), ); } /// 获取深色主题 static ThemeData get darkTheme { return ThemeData( useMaterial3: true, brightness: Brightness.dark, colorScheme: const ColorScheme.dark( primary: darkPrimaryColor, secondary: darkSecondaryColor, tertiary: darkAccentColor, surface: darkSurfaceBg, error: Color(0xFFCF6679), onPrimary: Colors.black, onSecondary: Colors.black, onSurface: darkTextPrimary, onError: Colors.black, ), scaffoldBackgroundColor: darkScaffoldBg, canvasColor: darkCanvasBg, cardColor: darkCardBg, dividerColor: darkDividerColor, // AppBar 主题 appBarTheme: const AppBarTheme( backgroundColor: darkSurfaceBg, foregroundColor: darkTextPrimary, elevation: 0, centerTitle: false, titleTextStyle: TextStyle( color: darkTextPrimary, fontSize: 20, fontWeight: FontWeight.w600, ), ), // 卡片主题 cardTheme: CardTheme( color: darkCardBg, elevation: 0, shadowColor: Colors.black26, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), side: const BorderSide(color: darkBorderColor, width: 1), ), ), // 按钮主题 elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: darkPrimaryColor, foregroundColor: Colors.black, elevation: 0, padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), ), // 文本字段主题 inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: darkSurfaceBg, border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: darkBorderColor), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: darkBorderColor), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: darkPrimaryColor, width: 2), ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: Color(0xFFCF6679)), ), contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), ), // 文本主题 textTheme: const TextTheme( displayLarge: TextStyle(color: darkTextPrimary, fontSize: 32, fontWeight: FontWeight.bold), displayMedium: TextStyle(color: darkTextPrimary, fontSize: 28, fontWeight: FontWeight.bold), displaySmall: TextStyle(color: darkTextPrimary, fontSize: 24, fontWeight: FontWeight.bold), headlineLarge: TextStyle(color: darkTextPrimary, fontSize: 22, fontWeight: FontWeight.w600), headlineMedium: TextStyle(color: darkTextPrimary, fontSize: 20, fontWeight: FontWeight.w600), headlineSmall: TextStyle(color: darkTextPrimary, fontSize: 18, fontWeight: FontWeight.w600), titleLarge: TextStyle(color: darkTextPrimary, fontSize: 16, fontWeight: FontWeight.w600), titleMedium: TextStyle(color: darkTextPrimary, fontSize: 14, fontWeight: FontWeight.w500), titleSmall: TextStyle(color: darkTextPrimary, fontSize: 12, fontWeight: FontWeight.w500), bodyLarge: TextStyle(color: darkTextPrimary, fontSize: 16), bodyMedium: TextStyle(color: darkTextPrimary, fontSize: 14), bodySmall: TextStyle(color: darkTextSecondary, fontSize: 12), labelLarge: TextStyle(color: darkTextPrimary, fontSize: 14, fontWeight: FontWeight.w500), labelMedium: TextStyle(color: darkTextSecondary, fontSize: 12), labelSmall: TextStyle(color: darkTextHint, fontSize: 10), ), // 图标主题 iconTheme: const IconThemeData( color: darkTextPrimary, size: 24, ), // 开关主题 switchTheme: SwitchThemeData( thumbColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.selected)) { return darkPrimaryColor; } return Colors.grey; }), trackColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.selected)) { return darkPrimaryColor.withOpacity(0.5); } return Colors.grey.shade700; }), ), // 复选框主题 checkboxTheme: CheckboxThemeData( fillColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.selected)) { return darkPrimaryColor; } return Colors.transparent; }), ), // 单选按钮主题 radioTheme: RadioThemeData( fillColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.selected)) { return darkPrimaryColor; } return Colors.grey; }), ), // 滑块主题 sliderTheme: SliderThemeData( activeTrackColor: darkPrimaryColor, inactiveTrackColor: darkPrimaryColor.withOpacity(0.3), thumbColor: darkPrimaryColor, overlayColor: darkPrimaryColor.withOpacity(0.12), ), // 底部导航栏主题 bottomNavigationBarTheme: const BottomNavigationBarThemeData( backgroundColor: darkSurfaceBg, selectedItemColor: darkPrimaryColor, unselectedItemColor: darkTextSecondary, type: BottomNavigationBarType.fixed, elevation: 8, ), // 导航抽屉主题 drawerTheme: const DrawerThemeData( backgroundColor: darkSurfaceBg, ), // 对话框主题 dialogTheme: DialogTheme( backgroundColor: darkSurfaceBg, elevation: 8, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), ), // 底部工作表主题 bottomSheetTheme: const BottomSheetThemeData( backgroundColor: darkSurfaceBg, elevation: 8, shape: RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(16)), ), ), ); } /// 获取画布背景色(根据主题) static Color getCanvasBg(BuildContext context) { return Theme.of(context).brightness == Brightness.dark ? darkCanvasBg : lightCanvasBg; } /// 获取网格颜色(根据主题) static Color getGridColor(BuildContext context) { return Theme.of(context).brightness == Brightness.dark ? darkGridColor : lightGridColor; } /// 获取元件颜色(根据主题) static Color getComponentColor(BuildContext context) { return Theme.of(context).brightness == Brightness.dark ? darkComponentColor : lightComponentColor; } /// 获取连线颜色(根据主题) static Color getWireColor(BuildContext context) { return Theme.of(context).brightness == Brightness.dark ? darkWireColor : lightWireColor; } /// 获取选中颜色(根据主题) static Color getSelectedColor(BuildContext context) { return Theme.of(context).brightness == Brightness.dark ? darkSelectedColor : lightSelectedColor; } }