import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:lucide_icons/lucide_icons.dart'; import 'package:google_fonts/google_fonts.dart'; import '../../providers/theme_provider.dart'; import '../../providers/ui_experiment_provider.dart'; import '../../theme/app_colors.dart'; class DisplaySettingsSection extends ConsumerWidget { const DisplaySettingsSection({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final userProfile = ref.watch(userProfileProvider); final experiment = ref.watch(uiExperimentProvider); final colorVariant = userProfile.colorVariant; final themeMode = userProfile.themeMode; final fontPref = userProfile.fontPreference; final appColors = Theme.of(context).extension()!; return Column( children: [ _buildSectionHeader(context, '表示設定', LucideIcons.monitor), Card( color: appColors.surfaceSubtle, child: Column( children: [ // 1. カラーテーマ ListTile( leading: Icon(LucideIcons.palette, color: appColors.iconDefault), title: Text('カラーテーマ', style: TextStyle(color: appColors.textPrimary)), subtitle: Text( colorVariant == 'washi_sumi_kohaku' ? '和紙×墨×琥珀' : 'Posimai Blue', style: TextStyle(color: appColors.textSecondary) ), trailing: Icon(LucideIcons.chevronRight, color: appColors.iconSubtle), onTap: () => _showColorThemeDialog(context, ref, colorVariant), ), Divider(height: 1, color: appColors.divider), // 2. グリッド列数 ListTile( leading: Icon(LucideIcons.grid, color: appColors.iconDefault), title: Text('グリッド表示', style: TextStyle(color: appColors.textPrimary)), subtitle: Text('${experiment.gridColumns}列表示', style: TextStyle(color: appColors.textSecondary)), trailing: Icon(LucideIcons.chevronRight, color: appColors.iconSubtle), onTap: () => _showGridColumnsDialog(context, ref, experiment.gridColumns), ), Divider(height: 1, color: appColors.divider), // 3. フォント ListTile( leading: Icon(LucideIcons.type, color: appColors.iconDefault), title: Text('フォント', style: TextStyle(color: appColors.textPrimary)), subtitle: Text(_getFontName(fontPref), style: TextStyle(color: appColors.textSecondary)), trailing: Icon(LucideIcons.chevronRight, color: appColors.iconSubtle), onTap: () => _showFontSelectionDialog(context, ref, fontPref), ), Divider(height: 1, color: appColors.divider), // 4. テーマモード ListTile( leading: Icon(LucideIcons.sunMoon, color: appColors.iconDefault), title: Text('明るさ', style: TextStyle(color: appColors.textPrimary)), subtitle: Text(_getThemeModeName(themeMode, context), style: TextStyle(color: appColors.textSecondary)), trailing: Icon(LucideIcons.chevronRight, color: appColors.iconSubtle), onTap: () => _showThemeDialog(context, ref, themeMode), ), ], ), ), ], ); } Widget _buildSectionHeader(BuildContext context, String title, IconData icon) { final appColors = Theme.of(context).extension()!; return Padding( padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 4), child: Row( children: [ Icon(icon, size: 20, color: appColors.iconDefault), const SizedBox(width: 8), Text( title, style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, color: appColors.textPrimary, ), ), ], ), ); } // カラーテーマダイアログ void _showColorThemeDialog(BuildContext context, WidgetRef ref, String current) { showDialog( context: context, builder: (context) => SimpleDialog( title: const Text('カラーテーマ'), children: [ _buildColorThemeOption(context, ref, 'washi_sumi_kohaku', '和紙×墨×琥珀', '日本酒の世界観', current), _buildColorThemeOption(context, ref, 'current', 'Posimai Blue', '既存のテーマ', current), ], ), ); } Widget _buildColorThemeOption(BuildContext context, WidgetRef ref, String value, String title, String subtitle, String current) { final appColors = Theme.of(context).extension()!; return SimpleDialogOption( onPressed: () { ref.read(userProfileProvider.notifier).setColorVariant(value); Navigator.pop(context); }, child: Row( children: [ Icon( value == current ? Icons.check_circle : Icons.circle_outlined, size: 20, color: value == current ? appColors.brandPrimary : appColors.iconSubtle, ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title, style: TextStyle(fontWeight: FontWeight.bold, color: appColors.textPrimary)), Text(subtitle, style: TextStyle(fontSize: 12, color: appColors.textSecondary)), ], ), ), ], ), ); } // グリッド列数ダイアログ void _showGridColumnsDialog(BuildContext context, WidgetRef ref, int current) { showDialog( context: context, builder: (context) => SimpleDialog( title: const Text('グリッド表示'), children: [ _buildGridOption(context, ref, 2, '2列表示', '標準サイズ(推奨)', current), _buildGridOption(context, ref, 3, '3列表示', 'コンパクト表示', current), ], ), ); } Widget _buildGridOption(BuildContext context, WidgetRef ref, int value, String title, String subtitle, int current) { final appColors = Theme.of(context).extension()!; return SimpleDialogOption( onPressed: () { ref.read(uiExperimentProvider.notifier).setGridColumns(value); Navigator.pop(context); }, child: Row( children: [ Icon( value == current ? Icons.check_circle : Icons.circle_outlined, size: 20, color: value == current ? appColors.brandPrimary : appColors.iconSubtle, ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title, style: TextStyle(fontWeight: FontWeight.bold, color: appColors.textPrimary)), Text(subtitle, style: TextStyle(fontSize: 12, color: appColors.textSecondary)), ], ), ), ], ), ); } // フォントダイアログ void _showFontSelectionDialog(BuildContext context, WidgetRef ref, String current) { showDialog( context: context, builder: (context) => SimpleDialog( title: Text('フォント設定', style: _getFontStyleForPreview(current, context)), children: [ _buildFontOption(context, ref, 'sans', 'ゴシック (標準)', current), _buildFontOption(context, ref, 'pottaOne', '髭文字 (和風)', current), _buildFontOption(context, ref, 'serif', '明朝 (上品)', current), _buildFontOption(context, ref, 'digital', 'ドット (レトロ)', current), ], ), ); } Widget _buildFontOption(BuildContext context, WidgetRef ref, String value, String label, String current) { final appColors = Theme.of(context).extension()!; return SimpleDialogOption( onPressed: () { ref.read(userProfileProvider.notifier).setFontPreference(value); Navigator.pop(context); }, child: Row( children: [ Icon( value == current ? Icons.check_circle : Icons.circle_outlined, size: 20, color: value == current ? appColors.brandPrimary : appColors.iconSubtle, ), const SizedBox(width: 16), Text( label, style: _getFontStyleForPreview(value, context), ), ], ), ); } TextStyle _getFontStyleForPreview(String fontValue, BuildContext context) { final appColors = Theme.of(context).extension()!; final baseStyle = TextStyle(color: appColors.textPrimary, fontSize: 16); switch (fontValue) { case 'pottaOne': return GoogleFonts.pottaOne(textStyle: baseStyle); case 'serif': return GoogleFonts.notoSerifJp(textStyle: baseStyle); case 'digital': return GoogleFonts.dotGothic16(textStyle: baseStyle); case 'sans': default: return GoogleFonts.notoSansJp(textStyle: baseStyle); } } String _getFontName(String pref) { switch (pref) { case 'pottaOne': return '髭文字 (和風)'; case 'serif': return '明朝 (上品)'; case 'digital': return 'ドット (レトロ)'; default: return 'ゴシック (標準)'; } } // テーマモードダイアログ void _showThemeDialog(BuildContext context, WidgetRef ref, String current) { showDialog( context: context, builder: (context) => SimpleDialog( title: const Text('テーマ設定'), children: [ _buildThemeOption(context, ref, 'system', 'システム設定', current), _buildThemeOption(context, ref, 'light', 'ライトモード', current), _buildThemeOption(context, ref, 'dark', 'ダークモード', current), _buildThemeOption(context, ref, 'auto_time', '時間連動 (20:00〜06:00)', current), ], ), ); } Widget _buildThemeOption(BuildContext context, WidgetRef ref, String value, String label, String current) { final appColors = Theme.of(context).extension()!; return SimpleDialogOption( onPressed: () { ref.read(userProfileProvider.notifier).setThemeMode(value); Navigator.pop(context); }, child: Row( children: [ Icon( value == current ? Icons.check_circle : Icons.circle_outlined, size: 20, color: value == current ? appColors.brandPrimary : appColors.iconSubtle, ), const SizedBox(width: 16), Text(label, style: TextStyle(color: appColors.textPrimary)), ], ), ); } String _getThemeModeName(String mode, BuildContext context) { switch (mode) { case 'light': return 'ライト'; case 'dark': return 'ダーク'; case 'auto_time': final isCurrentlyDark = Theme.of(context).brightness == Brightness.dark; return '時間連動 (${isCurrentlyDark ? '現在: ダーク' : '現在: ライト'})'; default: return 'システム設定'; } } }