MoodCanvas/lib/screens/preview/full_screen_preview_dialog.dart
fengshengxiong 91b7eebbf2 接入TopON
2026-01-22 16:34:55 +08:00

354 lines
10 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle, ByteData;
import 'dart:ui' as ui;
import 'package:aesthetica_wallpaper/models/recipe.dart';
import 'wallpaper_preview_painter.dart';
// 全屏预览对话框
class FullScreenPreviewDialog extends StatefulWidget {
final Recipe recipe;
const FullScreenPreviewDialog({super.key, required this.recipe});
@override
State<FullScreenPreviewDialog> createState() =>
_FullScreenPreviewDialogState();
}
class _FullScreenPreviewDialogState extends State<FullScreenPreviewDialog> {
bool _isHomeScreen = true; // true = 主页, false = 锁屏
ui.Image? _loadedImage;
bool _isLoading = true;
@override
void initState() {
super.initState();
_loadImage();
}
// 异步加载图片
Future<void> _loadImage() async {
try {
final ByteData data = await rootBundle.load(widget.recipe.baseImagePath);
final ui.Codec codec = await ui.instantiateImageCodec(
data.buffer.asUint8List(),
);
final ui.FrameInfo fi = await codec.getNextFrame();
if (mounted) {
setState(() {
_loadedImage = fi.image;
_isLoading = false;
});
}
} catch (e) {
if (mounted) {
setState(() => _isLoading = false);
}
debugPrint("Error loading image: $e");
}
}
@override
Widget build(BuildContext context) {
final screenSize = MediaQuery.of(context).size;
final isSmallScreen = screenSize.width < 600 || screenSize.height < 800;
return Dialog(
backgroundColor: Colors.transparent,
insetPadding: EdgeInsets.all(isSmallScreen ? 8 : 16),
child: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(isSmallScreen ? 12 : 20),
),
child: Stack(
children: [
// 全屏壁纸预览
Positioned.fill(
child: ClipRRect(
borderRadius: BorderRadius.circular(isSmallScreen ? 12 : 20),
child: _buildWallpaperPreview(isSmallScreen),
),
),
// 顶部控制栏
Positioned(
top: 0,
left: 0,
right: 0,
child: Container(
padding: EdgeInsets.symmetric(
horizontal: isSmallScreen ? 12 : 20,
vertical: isSmallScreen ? 8 : 16,
),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.black.withValues(alpha: 0.8),
Colors.transparent,
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// 关闭按钮
IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: Icon(
Icons.close,
color: Colors.white,
size: isSmallScreen ? 20 : 24,
),
padding: EdgeInsets.all(isSmallScreen ? 4 : 8),
constraints: const BoxConstraints(),
),
// 预览模式切换
Container(
decoration: BoxDecoration(
color: Colors.black.withValues(alpha: 0.5),
borderRadius: BorderRadius.circular(
isSmallScreen ? 16 : 20,
),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
_buildModeButton(
'Home',
Icons.home,
true,
isSmallScreen,
),
_buildModeButton(
'Lock',
Icons.lock,
false,
isSmallScreen,
),
],
),
),
],
),
),
),
],
),
),
);
}
Widget _buildModeButton(
String label,
IconData icon,
bool isHome,
bool isSmallScreen,
) {
final isSelected = _isHomeScreen == isHome;
return GestureDetector(
onTap: () {
setState(() {
_isHomeScreen = isHome;
});
},
child: Container(
padding: EdgeInsets.symmetric(
horizontal: isSmallScreen ? 10 : 16,
vertical: isSmallScreen ? 6 : 8,
),
decoration: BoxDecoration(
color: isSelected ? Colors.pinkAccent : Colors.transparent,
borderRadius: BorderRadius.circular(isSmallScreen ? 12 : 16),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
icon,
color: isSelected ? Colors.white : Colors.grey[400],
size: isSmallScreen ? 14 : 16,
),
SizedBox(width: isSmallScreen ? 3 : 4),
Text(
label,
style: TextStyle(
color: isSelected ? Colors.white : Colors.grey[400],
fontSize: isSmallScreen ? 11 : 12,
fontWeight: FontWeight.w500,
),
),
],
),
),
);
}
Widget _buildWallpaperPreview(bool isSmallScreen) {
if (_isLoading) {
return Container(
color: Colors.black,
child: const Center(
child: CircularProgressIndicator(color: Colors.pinkAccent),
),
);
}
if (_loadedImage == null) {
return Container(
color: Colors.grey[800],
child: const Center(
child: Icon(Icons.image_not_supported, color: Colors.grey, size: 60),
),
);
}
return Stack(
fit: StackFit.expand,
children: [
// 壁纸图片
CustomPaint(
painter: WallpaperPreviewPainter(
image: _loadedImage!,
recipe: widget.recipe,
),
child: Container(),
),
// UI覆盖层
_isHomeScreen
? _buildHomeScreenUI(isSmallScreen)
: _buildLockScreenUI(isSmallScreen),
],
);
}
Widget _buildHomeScreenUI(bool isSmallScreen) {
return Stack(
children: [
// 模拟主页内容
Positioned(
top: isSmallScreen ? 30 : 50,
left: isSmallScreen ? 12 : 20,
right: isSmallScreen ? 12 : 20,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Good Morning',
style: TextStyle(
color: Colors.white,
fontSize: isSmallScreen ? 18 : 24,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: isSmallScreen ? 4 : 8),
Text(
'Monday, October 23',
style: TextStyle(
color: Colors.white.withValues(alpha: 0.8),
fontSize: isSmallScreen ? 13 : 16,
),
),
],
),
),
// 底部Dock
Positioned(
bottom: isSmallScreen ? 12 : 20,
left: isSmallScreen ? 12 : 20,
right: isSmallScreen ? 12 : 20,
child: Container(
padding: EdgeInsets.symmetric(
horizontal: isSmallScreen ? 12 : 20,
vertical: isSmallScreen ? 8 : 12,
),
decoration: BoxDecoration(
color: Colors.black.withValues(alpha: 0.3),
borderRadius: BorderRadius.circular(isSmallScreen ? 16 : 20),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildDockIcon(Icons.phone, isSmallScreen),
_buildDockIcon(Icons.message, isSmallScreen),
_buildDockIcon(Icons.camera_alt, isSmallScreen),
_buildDockIcon(Icons.music_note, isSmallScreen),
],
),
),
),
],
);
}
Widget _buildLockScreenUI(bool isSmallScreen) {
return Stack(
children: [
// 时间显示
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'9:41',
style: TextStyle(
color: Colors.white,
fontSize: isSmallScreen ? 36 : 48,
fontWeight: FontWeight.w300,
),
),
SizedBox(height: isSmallScreen ? 4 : 8),
Text(
'Monday, October 23',
style: TextStyle(
color: Colors.white.withValues(alpha: 0.8),
fontSize: isSmallScreen ? 13 : 16,
),
),
],
),
),
// 底部控制
Positioned(
bottom: isSmallScreen ? 30 : 50,
left: 0,
right: 0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildLockIcon(Icons.flashlight_off, isSmallScreen),
_buildLockIcon(Icons.camera_alt, isSmallScreen),
],
),
),
],
);
}
Widget _buildDockIcon(IconData icon, bool isSmallScreen) {
return Container(
padding: EdgeInsets.all(isSmallScreen ? 8 : 12),
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(isSmallScreen ? 10 : 12),
),
child: Icon(icon, color: Colors.white, size: isSmallScreen ? 20 : 24),
);
}
Widget _buildLockIcon(IconData icon, bool isSmallScreen) {
return Container(
padding: EdgeInsets.all(isSmallScreen ? 12 : 16),
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.2),
shape: BoxShape.circle,
),
child: Icon(icon, color: Colors.white, size: isSmallScreen ? 20 : 24),
);
}
}