home_page.dart 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_screenutil/flutter_screenutil.dart';
  3. import 'package:get/get.dart';
  4. import 'package:gobang/components/game_action_bar.dart';
  5. import 'package:gobang/components/game_status_text.dart';
  6. import 'package:gobang/controllers/game_controller.dart';
  7. import 'package:gobang/routes/app_routes.dart';
  8. import 'package:gobang/themes/app_colors.dart';
  9. import 'package:gobang/widgets/gobang_board.dart';
  10. class HomePage extends GetView<GameController> {
  11. const HomePage({super.key});
  12. @override
  13. Widget build(BuildContext context) {
  14. return Obx(() {
  15. final theme = controller.themeFactory.value.getTheme();
  16. final _ = controller.useCircle.value;
  17. final boardSize = (1.sw * 0.82).clamp(0.0, 1.sh * 0.52);
  18. final isDark = theme.isDark;
  19. return Scaffold(
  20. extendBodyBehindAppBar: true,
  21. appBar: AppBar(
  22. elevation: 0,
  23. backgroundColor: Colors.transparent,
  24. foregroundColor: AppColors.ivory,
  25. title: Text(
  26. '南瓜五子棋',
  27. style: TextStyle(
  28. fontWeight: FontWeight.w800,
  29. fontSize: 22.sp,
  30. letterSpacing: 0.6,
  31. ),
  32. ),
  33. actions: [
  34. _GlassIconButton(
  35. onPressed: controller.toggleTheme,
  36. icon: controller.currentLight,
  37. ),
  38. _GlassIconButton(
  39. onPressed: controller.toggleShape,
  40. icon: controller.currentShape,
  41. ),
  42. _GlassIconButton(
  43. onPressed: () => Get.toNamed(AppRoutes.settings),
  44. icon: const Icon(Icons.tune_rounded, color: AppColors.ivory),
  45. ),
  46. SizedBox(width: 8.w),
  47. ],
  48. ),
  49. body: Container(
  50. width: double.infinity,
  51. decoration: BoxDecoration(
  52. gradient: LinearGradient(
  53. colors: theme.gradient,
  54. begin: Alignment.topCenter,
  55. end: Alignment.bottomCenter,
  56. stops: const [0, 0.42, 1],
  57. ),
  58. ),
  59. child: SafeArea(
  60. child: SingleChildScrollView(
  61. padding: EdgeInsets.fromLTRB(20.w, 8.h, 20.w, 24.h),
  62. child: Column(
  63. children: [
  64. const GameStatusText(),
  65. SizedBox(height: 20.h),
  66. Container(
  67. padding: EdgeInsets.all(16.w),
  68. decoration: BoxDecoration(
  69. color: isDark ? AppColors.darkSurface : AppColors.ivory,
  70. borderRadius: BorderRadius.circular(24.r),
  71. boxShadow: [
  72. BoxShadow(
  73. color: AppColors.ink.withValues(alpha: 0.28),
  74. blurRadius: 28,
  75. offset: const Offset(0, 12),
  76. spreadRadius: -4,
  77. ),
  78. ],
  79. ),
  80. child: GobangBoard(size: boardSize.toDouble()),
  81. ),
  82. SizedBox(height: 20.h),
  83. const GameActionBar(),
  84. SizedBox(height: 12.h),
  85. Text(
  86. '你执白 · AI 执黑',
  87. style: TextStyle(
  88. color: isDark
  89. ? AppColors.muted
  90. : AppColors.muted.withValues(alpha: 0.9),
  91. fontSize: 12.sp,
  92. ),
  93. ),
  94. ],
  95. ),
  96. ),
  97. ),
  98. ),
  99. );
  100. });
  101. }
  102. }
  103. class _GlassIconButton extends StatelessWidget {
  104. const _GlassIconButton({required this.onPressed, required this.icon});
  105. final VoidCallback onPressed;
  106. final Widget icon;
  107. @override
  108. Widget build(BuildContext context) {
  109. return Padding(
  110. padding: EdgeInsets.symmetric(horizontal: 2.w),
  111. child: Material(
  112. color: Colors.white.withValues(alpha: 0.18),
  113. borderRadius: BorderRadius.circular(12.r),
  114. child: InkWell(
  115. onTap: onPressed,
  116. borderRadius: BorderRadius.circular(12.r),
  117. child: SizedBox(
  118. width: 40.w,
  119. height: 40.w,
  120. child: Center(child: icon),
  121. ),
  122. ),
  123. ),
  124. );
  125. }
  126. }