import 'package:flutter/material.dart'; import 'package:flutter_colorpicker/flutter_colorpicker.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../models/pen_tool.dart'; import '../models/pressure_curve.dart'; import '../providers/settings_provider.dart'; import '../utils/stroke_stabilizer.dart'; /// Material 3 settings screen for BadNote. class SettingsScreen extends ConsumerWidget { const SettingsScreen({super.key}); void _showColorPicker( BuildContext context, Color current, ValueChanged onPicked, ) { Color pickerColor = current; showDialog( context: context, builder: (context) { return AlertDialog( title: const Text('Pick a color'), content: SingleChildScrollView( child: ColorPicker( pickerColor: pickerColor, onColorChanged: (color) => pickerColor = color, ), ), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), child: const Text('Cancel'), ), TextButton( onPressed: () { onPicked(pickerColor); Navigator.of(context).pop(); }, child: const Text('OK'), ), ], ); }, ); } void _confirmClearData(BuildContext context, WidgetRef ref) { showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('Clear all local settings?'), content: const Text( 'This will reset pen defaults and appearance settings. ' 'Notes and documents are not affected.', ), actions: [ TextButton( onPressed: () => Navigator.pop(ctx), child: const Text('Cancel'), ), TextButton( onPressed: () { ref.read(settingsProvider).clearAllData(); Navigator.pop(ctx); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Settings reset to defaults')), ); }, child: const Text('Clear'), ), ], ), ); } @override Widget build(BuildContext context, WidgetRef ref) { final settings = ref.watch(settingsProvider); final colorScheme = Theme.of(context).colorScheme; return Scaffold( appBar: AppBar(title: const Text('Settings')), body: ListView( children: [ _SectionHeader(title: 'Defaults', icon: Icons.tune), Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Default Tool', style: TextStyle(fontWeight: FontWeight.w500), ), const SizedBox(height: 4), DropdownButtonFormField( initialValue: settings.defaultTool, decoration: const InputDecoration( border: OutlineInputBorder(), isDense: true, ), items: PenTool.values.map((tool) { return DropdownMenuItem( value: tool, child: Text(tool.name), ); }).toList(), onChanged: (tool) { if (tool != null) settings.setDefaultTool(tool); }, ), const SizedBox(height: 16), const Text( 'Default Color', style: TextStyle(fontWeight: FontWeight.w500), ), const SizedBox(height: 4), Row( children: [ MouseRegion( cursor: SystemMouseCursors.click, child: InkWell( borderRadius: BorderRadius.circular(8), onTap: () => _showColorPicker( context, settings.defaultColor, settings.setDefaultColor, ), child: Container( width: 40, height: 40, decoration: BoxDecoration( color: settings.defaultColor, borderRadius: BorderRadius.circular(8), border: Border.all(color: colorScheme.outline), ), ), ), ), const SizedBox(width: 12), Text( '#${settings.defaultColor.toARGB32().toRadixString(16).padLeft(8, '0').toUpperCase()}', style: const TextStyle(fontFamily: 'monospace'), ), ], ), const SizedBox(height: 16), const Text( 'Default Stroke Width', style: TextStyle(fontWeight: FontWeight.w500), ), Slider( value: settings.defaultStrokeWidth, min: 1.0, max: 20.0, divisions: 19, label: settings.defaultStrokeWidth.toStringAsFixed(1), onChanged: settings.setDefaultStrokeWidth, ), const SizedBox(height: 16), const Text( 'Pressure Curve', style: TextStyle(fontWeight: FontWeight.w500), ), const SizedBox(height: 4), DropdownButtonFormField( initialValue: settings.defaultPressureCurve, decoration: const InputDecoration( border: OutlineInputBorder(), isDense: true, ), items: PressureCurveType.values.map((curve) { return DropdownMenuItem( value: curve, child: Text(curve.name), ); }).toList(), onChanged: (curve) { if (curve != null) { settings.setDefaultPressureCurve(curve); } }, ), const SizedBox(height: 16), const Text( 'Stabilization', style: TextStyle(fontWeight: FontWeight.w500), ), const SizedBox(height: 4), DropdownButtonFormField( initialValue: settings.defaultStabilization, decoration: const InputDecoration( border: OutlineInputBorder(), isDense: true, ), items: StabilizationLevel.values.map((level) { return DropdownMenuItem( value: level, child: Text(level.name), ); }).toList(), onChanged: (level) { if (level != null) settings.setDefaultStabilization(level); }, ), ], ), ), const Divider(), _SectionHeader(title: 'Appearance', icon: Icons.palette), Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Theme Mode', style: TextStyle(fontWeight: FontWeight.w500), ), const SizedBox(height: 4), SegmentedButton( segments: const [ ButtonSegment( value: ThemeMode.system, label: Text('System'), icon: Icon(Icons.brightness_auto), ), ButtonSegment( value: ThemeMode.light, label: Text('Light'), icon: Icon(Icons.light_mode), ), ButtonSegment( value: ThemeMode.dark, label: Text('Dark'), icon: Icon(Icons.dark_mode), ), ], selected: {settings.themeMode}, onSelectionChanged: (modes) { settings.setThemeMode(modes.first); }, ), const SizedBox(height: 16), const Text( 'Color Scheme Seed', style: TextStyle(fontWeight: FontWeight.w500), ), const SizedBox(height: 4), Row( children: [ MouseRegion( cursor: SystemMouseCursors.click, child: InkWell( borderRadius: BorderRadius.circular(8), onTap: () => _showColorPicker( context, settings.colorSchemeSeed, settings.setColorSchemeSeed, ), child: Container( width: 40, height: 40, decoration: BoxDecoration( color: settings.colorSchemeSeed, borderRadius: BorderRadius.circular(8), border: Border.all(color: colorScheme.outline), ), ), ), ), const SizedBox(width: 12), const Text('Seed color for Material 3 theme'), ], ), ], ), ), const Divider(), _SectionHeader(title: 'About', icon: Icons.info), Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'BadNote v0.1.0', style: TextStyle(fontWeight: FontWeight.w500), ), const SizedBox(height: 4), Text( 'Local-first Surface Pen note-taking with PDF/PPT annotation. ' 'OCR and search run entirely on your device.', style: TextStyle( fontSize: 13, color: colorScheme.onSurfaceVariant, ), ), const SizedBox(height: 16), OutlinedButton.icon( onPressed: () => _confirmClearData(context, ref), icon: const Icon(Icons.delete_forever, color: Colors.red), label: const Text( 'Clear All Local Settings', style: TextStyle(color: Colors.red), ), ), ], ), ), const SizedBox(height: 32), ], ), ); } } class _SectionHeader extends StatelessWidget { final String title; final IconData icon; const _SectionHeader({required this.title, required this.icon}); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.fromLTRB(16, 16, 16, 4), child: Row( children: [ Icon(icon, size: 20, color: Theme.of(context).colorScheme.primary), const SizedBox(width: 8), Text( title, style: Theme.of( context, ).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold), ), ], ), ); } }