LineInkGuide/lib/skin_shop_screen.dart

208 lines
7.6 KiB
Dart

import 'package:flutter/material.dart';
import 'app_theme.dart';
import 'managers.dart';
class SkinShopScreen extends StatefulWidget {
const SkinShopScreen({super.key});
@override
State<SkinShopScreen> createState() => _SkinShopScreenState();
}
class _SkinShopScreenState extends State<SkinShopScreen> {
@override
Widget build(BuildContext context) {
final manager = LevelManager.instance;
return Scaffold(
backgroundColor: AppTheme.paperBg,
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
iconTheme: const IconThemeData(color: AppTheme.inkPrimary),
title: const Text(
'SKINS',
style: TextStyle(
color: AppTheme.inkPrimary,
fontWeight: FontWeight.bold,
),
),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: const EdgeInsets.all(16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'STAR SHOP',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: AppTheme.inkPrimary,
),
),
Row(
children: [
const Icon(Icons.star, color: AppTheme.accentYellow),
const SizedBox(width: 4),
Text(
'${manager.totalStars}',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: AppTheme.inkPrimary,
),
),
],
),
],
),
),
const Divider(height: 1),
Expanded(
child: GridView.builder(
padding: const EdgeInsets.all(16),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 16,
crossAxisSpacing: 16,
childAspectRatio: 0.9,
),
itemCount: SkinManager.skins.length,
itemBuilder: (context, index) {
final skin = SkinManager.skins[index];
final owned = manager.isSkinOwned(skin.id);
final selected = manager.isSkinSelected(skin.id);
final canAfford = manager.canAfford(skin.cost);
return Container(
decoration: BoxDecoration(
border: Border.all(
color: selected
? AppTheme.accentGreen
: AppTheme.inkPrimary,
width: selected ? 3 : 1.5,
),
color: Colors.white,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Skin preview: one ball
Container(
width: 64,
height: 64,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: skin.ballColor,
boxShadow: const [
BoxShadow(
color: Colors.black26,
blurRadius: 4,
offset: Offset(0, 2),
),
],
),
child: Align(
alignment: const Alignment(-0.4, -0.4),
child: Container(
width: 18,
height: 18,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: skin.eyeColor,
),
),
),
),
const SizedBox(height: 8),
Text(
skin.name,
style: const TextStyle(
fontWeight: FontWeight.bold,
color: AppTheme.inkPrimary,
),
),
const SizedBox(height: 4),
if (skin.cost > 0)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(
Icons.star,
size: 16,
color: AppTheme.accentYellow,
),
const SizedBox(width: 2),
Text(
'${skin.cost}',
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: AppTheme.inkPrimary,
),
),
],
)
else
const Text(
'DEFAULT SKIN',
style: TextStyle(
fontSize: 12,
color: AppTheme.gridLine,
),
),
const SizedBox(height: 8),
SizedBox(
width: 128,
child: OutlinedButton(
style: OutlinedButton.styleFrom(
side: BorderSide(
color: owned
? AppTheme.accentGreen
: (canAfford
? AppTheme.inkPrimary
: AppTheme.gridLine),
),
),
onPressed: () {
setState(() {
if (!owned) {
final success = manager.buySkin(skin);
if (!success) return;
} else {
manager.selectSkin(skin.id);
}
});
},
child: Text(
owned
? (selected ? 'EQUIPPED' : 'EQUIP')
: (canAfford ? 'UNLOCK' : 'NOT ENOUGH STARS'),
style: TextStyle(
color: owned
? AppTheme.accentGreen
: (canAfford
? AppTheme.inkPrimary
: AppTheme.gridLine),
fontWeight: FontWeight.bold,
fontSize: 11,
),
),
),
),
],
),
);
},
),
),
],
),
);
}
}