134 lines
3.8 KiB
Dart
134 lines
3.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import '../../game/models.dart';
|
|
import '../../game/enums.dart';
|
|
import '../../utils.dart';
|
|
import '../../game/config.dart';
|
|
|
|
class ItemCardWidget extends StatelessWidget {
|
|
final Item item;
|
|
final VoidCallback? onTap;
|
|
final bool showPrice;
|
|
final bool canBuy;
|
|
|
|
const ItemCardWidget({
|
|
super.key,
|
|
required this.item,
|
|
this.onTap,
|
|
this.showPrice = false,
|
|
this.canBuy = true,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return InkWell(
|
|
onTap: onTap,
|
|
child: Card(
|
|
color: ThemeConfig.shopItemCardBg, // Configurable if needed
|
|
shape: item.rarity != ItemRarity.magic
|
|
? RoundedRectangleBorder(
|
|
side: BorderSide(
|
|
color: ItemUtils.getRarityColor(item.rarity),
|
|
width: 2.0,
|
|
),
|
|
borderRadius: BorderRadius.circular(8.0),
|
|
)
|
|
: null,
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(4.0),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Expanded(
|
|
child: Image.asset(
|
|
ItemUtils.getIconPath(item.slot),
|
|
fit: BoxFit.contain,
|
|
),
|
|
),
|
|
Text(
|
|
item.name,
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
style: TextStyle(
|
|
fontWeight: FontWeight.bold,
|
|
color: ItemUtils.getRarityColor(item.rarity),
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
// Show Item Stats (Fixed to show negative values)
|
|
FittedBox(fit: BoxFit.scaleDown, child: _buildItemStatText(item)),
|
|
if (showPrice) ...[
|
|
const Spacer(),
|
|
Text(
|
|
"${item.price} G",
|
|
style: TextStyle(
|
|
color: canBuy
|
|
? ThemeConfig.statGoldColor
|
|
: ThemeConfig.textColorGrey,
|
|
fontWeight: FontWeight.bold,
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
],
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildItemStatText(Item item) {
|
|
List<String> stats = [];
|
|
|
|
// Helper to format stat string
|
|
String formatStat(int value, String label) {
|
|
String sign = value > 0 ? "+" : ""; // Negative values already have '-'
|
|
return "$sign$value $label";
|
|
}
|
|
|
|
if (item.atkBonus != 0) {
|
|
stats.add(formatStat(item.atkBonus, AppStrings.atk));
|
|
}
|
|
if (item.hpBonus != 0) {
|
|
stats.add(formatStat(item.hpBonus, AppStrings.hp));
|
|
}
|
|
if (item.armorBonus != 0) {
|
|
stats.add(formatStat(item.armorBonus, AppStrings.def));
|
|
}
|
|
if (item.luck != 0) {
|
|
stats.add(formatStat(item.luck, AppStrings.luck));
|
|
}
|
|
|
|
List<String> effectTexts = item.effects.map((e) => e.description).toList();
|
|
|
|
if (stats.isEmpty && effectTexts.isEmpty) return const SizedBox.shrink();
|
|
|
|
return Column(
|
|
children: [
|
|
if (stats.isNotEmpty)
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 2.0, bottom: 2.0),
|
|
child: Text(
|
|
stats.join(", "),
|
|
style: const TextStyle(
|
|
fontSize: ThemeConfig.fontSizeSmall,
|
|
color: ThemeConfig.statAtkColor,
|
|
),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
),
|
|
if (effectTexts.isNotEmpty)
|
|
Padding(
|
|
padding: const EdgeInsets.only(bottom: 2.0),
|
|
child: Text(
|
|
effectTexts.join("\n"),
|
|
style: const TextStyle(
|
|
fontSize: ThemeConfig.fontSizeTiny,
|
|
color: ThemeConfig.rarityLegendary,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|