// =========================================================================== // FILE: lib/ui/settings/settings_screen.dart // =========================================================================== import 'dart:ui'; // <--- IMPORTANTE: Aggiunto per ImageFilter.blur import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../core/theme_manager.dart'; import '../../core/app_colors.dart'; import '../../services/storage_service.dart'; import '../../widgets/painters.dart'; class SettingsScreen extends StatefulWidget { const SettingsScreen({super.key}); @override State createState() => _SettingsScreenState(); } class _SettingsScreenState extends State { @override Widget build(BuildContext context) { final themeManager = context.watch(); final theme = themeManager.currentColors; final themeType = themeManager.currentThemeType; int playerLevel = StorageService.instance.playerLevel; final double screenHeight = MediaQuery.of(context).size.height; final double vScale = (screenHeight / 920.0).clamp(0.7, 1.2); return Scaffold( backgroundColor: theme.background, extendBodyBehindAppBar: true, appBar: AppBar( toolbarHeight: 80 * vScale, title: Container( padding: EdgeInsets.symmetric(horizontal: 24 * vScale, vertical: 10 * vScale), decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ Colors.white.withOpacity(0.3), Colors.white.withOpacity(0.05), ], ), borderRadius: BorderRadius.circular(15), border: Border.all(color: Colors.white.withOpacity(0.5), width: 1.5), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.2), blurRadius: 10, offset: const Offset(0, 4), ) ], ), child: Text( "SELEZIONA TEMA", style: getSharedTextStyle(themeType, TextStyle( fontWeight: FontWeight.w900, color: Colors.white, letterSpacing: 2.0, fontSize: 20 * vScale, shadows: [Shadow(color: Colors.black.withOpacity(0.8), blurRadius: 5, offset: const Offset(2, 2))] )) ), ), centerTitle: true, backgroundColor: Colors.transparent, elevation: 0, iconTheme: IconThemeData(color: Colors.white, size: 28 * vScale), ), body: Stack( children: [ Container(color: themeType == AppThemeType.doodle ? Colors.white : theme.background), Positioned.fill( child: Container( decoration: BoxDecoration( image: DecorationImage( image: const AssetImage('assets/images/sfondo_temi.jpg'), fit: BoxFit.cover, colorFilter: ColorFilter.mode(Colors.black.withOpacity(0.6), BlendMode.darken), ), ), ), ), ListView( padding: EdgeInsets.only(top: 120 * vScale, left: 20 * vScale, right: 20 * vScale, bottom: 40 * vScale), physics: const BouncingScrollPhysics(), children: [ _ThemeCard( title: "Quaderno", subtitle: "Sfondo a quadretti, tratto a penna", type: AppThemeType.doodle, previewColors: AppColors.doodle, requiredLevel: 1, currentLevel: playerLevel, vScale: vScale, ), SizedBox(height: 25 * vScale), _ThemeCard( title: "Cyberpunk", subtitle: "Nero profondo, luci al neon", type: AppThemeType.cyberpunk, previewColors: AppColors.cyberpunk, requiredLevel: 3, currentLevel: playerLevel, vScale: vScale, ), SizedBox(height: 25 * vScale), _ThemeCard( title: "8-Bit Arcade", subtitle: "Sale giochi, fosfori verdi e pixel", type: AppThemeType.arcade, previewColors: AppColors.arcade, requiredLevel: 7, currentLevel: playerLevel, vScale: vScale, ), SizedBox(height: 25 * vScale), _ThemeCard( title: "Grimorio", subtitle: "Incantesimi antichi, rune magiche", type: AppThemeType.grimorio, previewColors: AppColors.grimorio, requiredLevel: 10, currentLevel: playerLevel, vScale: vScale, ), SizedBox(height: 25 * vScale), _ThemeCard( title: "Musica", subtitle: "Vinili, cassette e vibrazioni sonore", type: AppThemeType.music, previewColors: AppColors.music, requiredLevel: 15, currentLevel: playerLevel, vScale: vScale, ), SizedBox(height: 40 * vScale), ], ), ], ), ); } } class _ThemeCard extends StatelessWidget { final String title; final String subtitle; final AppThemeType type; final ThemeColors previewColors; final int requiredLevel; final int currentLevel; final double vScale; const _ThemeCard({ required this.title, required this.subtitle, required this.type, required this.previewColors, required this.requiredLevel, required this.currentLevel, required this.vScale, }); @override Widget build(BuildContext context) { final themeManager = context.watch(); bool isSelected = themeManager.currentThemeType == type; bool isLocked = currentLevel < requiredLevel; String? bgImage; if (type == AppThemeType.doodle) bgImage = 'assets/images/doodle_bg.jpg'; if (type == AppThemeType.cyberpunk) bgImage = 'assets/images/cyber_bg.jpg'; if (type == AppThemeType.music) bgImage = 'assets/images/music_bg.jpg'; if (type == AppThemeType.arcade) bgImage = 'assets/images/arcade.jpg'; if (type == AppThemeType.grimorio) bgImage = 'assets/images/grimorio.jpg'; Border border; List shadows = [ BoxShadow(color: Colors.black.withOpacity(0.8), offset: const Offset(0, 10), blurRadius: 15) ]; if (type == AppThemeType.doodle) { border = Border.all(color: isSelected ? previewColors.playerBlue : const Color(0xFF111122).withOpacity(0.8), width: isSelected ? 4 : 2); if (isSelected) shadows.add(const BoxShadow(color: Color(0xFF111122), offset: Offset(4, 5))); } else if (type == AppThemeType.cyberpunk || type == AppThemeType.music) { border = Border.all(color: isSelected ? previewColors.playerBlue : previewColors.gridLine.withOpacity(0.8), width: isSelected ? 3 : 1.5); if (isSelected) shadows.add(BoxShadow(color: previewColors.playerBlue.withOpacity(0.8), blurRadius: 25, spreadRadius: 3)); } else if (type == AppThemeType.arcade) { border = Border.all(color: isSelected ? previewColors.gridLine : Colors.white54, width: isSelected ? 4 : 2); if (isSelected) shadows.add(BoxShadow(color: previewColors.gridLine.withOpacity(0.5), offset: const Offset(4, 4))); } else { border = Border.all(color: isSelected ? Colors.amber : previewColors.gridLine.withOpacity(0.8), width: isSelected ? 3 : 1.5); if (isSelected) shadows.add(BoxShadow(color: Colors.amber.withOpacity(0.6), blurRadius: 20)); } return GestureDetector( onTap: () { if (isLocked) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text("Gioca per raggiungere il Liv. $requiredLevel e sbloccare questo tema!", style: const TextStyle(fontWeight: FontWeight.bold, color: Colors.white)), backgroundColor: Colors.redAccent, behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), duration: const Duration(seconds: 2), ) ); return; } themeManager.setTheme(type); Navigator.pop(context); }, child: AnimatedContainer( duration: const Duration(milliseconds: 300), height: 140 * vScale, padding: EdgeInsets.symmetric(horizontal: 20 * vScale, vertical: 15 * vScale), decoration: BoxDecoration( color: isLocked ? Colors.black87 : previewColors.background, borderRadius: BorderRadius.circular(20), border: border, boxShadow: shadows, image: bgImage != null ? DecorationImage( image: AssetImage(bgImage!), fit: BoxFit.cover, colorFilter: type == AppThemeType.doodle ? ColorFilter.mode(Colors.white.withOpacity(isLocked ? 0.9 : 0.4), BlendMode.lighten) : ColorFilter.mode(Colors.black.withOpacity(isLocked ? 0.85 : 0.5), BlendMode.darken), ) : null, ), child: Stack( alignment: Alignment.center, children: [ Opacity( opacity: isLocked ? 0.3 : 1.0, child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( // --- CORNICE EFFETTO VETRO (GLASSMORPHISM) --- child: ClipRRect( borderRadius: BorderRadius.circular(12), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 6.0, sigmaY: 6.0), child: Container( padding: EdgeInsets.symmetric(horizontal: 15 * vScale, vertical: 10 * vScale), decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ Colors.white.withOpacity(0.5), // Più visibile in alto a sx Colors.white.withOpacity(0.1), // Quasi trasparente in basso a dx ], ), borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.white.withOpacity(0.3), width: 1.5), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ FittedBox( fit: BoxFit.scaleDown, alignment: Alignment.centerLeft, child: Text( title, style: getSharedTextStyle( type, TextStyle( fontSize: (type == AppThemeType.arcade ? 15 : 22) * vScale, fontWeight: FontWeight.w900, color: const Color(0xFF111122), letterSpacing: type == AppThemeType.music ? 1.5 : 0.5, ) ) ), ), SizedBox(height: 4 * vScale), FittedBox( fit: BoxFit.scaleDown, alignment: Alignment.centerLeft, child: Text( subtitle, style: getSharedTextStyle( type, TextStyle( fontSize: (type == AppThemeType.arcade ? 8 : 12) * vScale, color: const Color(0xFF333344), fontWeight: FontWeight.bold, ) ) ), ), ], ), ), ), ), ), SizedBox(width: 15 * vScale), Container( width: 28 * vScale, height: 28 * vScale, decoration: BoxDecoration( color: previewColors.playerRed, shape: type == AppThemeType.arcade ? BoxShape.rectangle : BoxShape.circle, border: Border.all(color: Colors.white, width: 2), boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.5), blurRadius: 5, offset: const Offset(1, 2))] ) ), SizedBox(width: 12 * vScale), Container( width: 28 * vScale, height: 28 * vScale, decoration: BoxDecoration( color: previewColors.playerBlue, shape: type == AppThemeType.arcade ? BoxShape.rectangle : BoxShape.circle, border: Border.all(color: Colors.white, width: 2), boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.5), blurRadius: 5, offset: const Offset(1, 2))] ) ), ], ), ), if (isLocked) Container( padding: EdgeInsets.symmetric(horizontal: 16 * vScale, vertical: 10 * vScale), decoration: BoxDecoration( color: Colors.black.withOpacity(0.95), borderRadius: BorderRadius.circular(20), border: Border.all(color: previewColors.playerRed.withOpacity(0.8), width: 2), boxShadow: [BoxShadow(color: previewColors.playerRed.withOpacity(0.5), blurRadius: 20)], ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.lock_rounded, color: Colors.white, size: 20 * vScale), SizedBox(width: 8 * vScale), Text( "LIV. $requiredLevel", style: getSharedTextStyle(type, TextStyle(color: Colors.white, fontWeight: FontWeight.w900, fontSize: 16 * vScale, letterSpacing: 2)) ), ], ), ), ], ), ), ); } }