Files
asciinevrdie/lib/src/features/game/widgets/desktop_equipment_panel.dart
JiWoong Sul 864a866039 refactor(ui): 위젯 분리 및 화면 개선
- game_play_screen에서 desktop 패널 위젯 분리
- death_overlay에서 death_buttons, death_combat_log 분리
- mobile_carousel_layout에서 mobile_options_menu 분리
- 아레나 위젯 개선 (arena_hp_bar, result_panel 등)
- settings_screen에서 retro_settings_widgets 분리
- 기타 위젯 리팩토링 및 import 경로 업데이트
2026-02-23 15:49:38 +09:00

169 lines
4.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:asciineverdie/data/game_text_l10n.dart' as game_l10n;
import 'package:asciineverdie/l10n/app_localizations.dart';
import 'package:asciineverdie/src/shared/l10n/game_data_l10n.dart';
import 'package:asciineverdie/src/core/model/game_state.dart';
import 'package:asciineverdie/src/core/model/inventory.dart';
import 'package:asciineverdie/src/features/game/widgets/combat_log.dart';
import 'package:asciineverdie/src/features/game/widgets/desktop_panel_widgets.dart';
import 'package:asciineverdie/src/features/game/widgets/equipment_stats_panel.dart';
import 'package:asciineverdie/src/features/game/widgets/potion_inventory_panel.dart';
import 'package:asciineverdie/src/shared/retro_colors.dart';
/// 데스크톱 중앙 패널: Equipment/Inventory
///
/// Equipment, Inventory, Potions, Encumbrance, Combat Log 표시
class DesktopEquipmentPanel extends StatelessWidget {
const DesktopEquipmentPanel({
super.key,
required this.state,
required this.combatLogEntries,
});
final GameState state;
final List<CombatLogEntry> combatLogEntries;
@override
Widget build(BuildContext context) {
final l10n = L10n.of(context);
return Card(
margin: const EdgeInsets.all(4),
color: RetroColors.panelBg,
shape: RoundedRectangleBorder(
side: const BorderSide(
color: RetroColors.panelBorderOuter,
width: 2,
),
borderRadius: BorderRadius.circular(0),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
DesktopPanelHeader(title: l10n.equipment),
Expanded(
flex: 2,
child: EquipmentStatsPanel(equipment: state.equipment),
),
DesktopPanelHeader(title: l10n.inventory),
Expanded(child: _InventoryList(state: state)),
DesktopSectionHeader(title: game_l10n.uiPotions),
Expanded(
child: PotionInventoryPanel(inventory: state.potionInventory),
),
DesktopSectionHeader(title: l10n.encumbrance),
DesktopSegmentProgressBar(
position: state.progress.encumbrance.position,
max: state.progress.encumbrance.max,
color: Colors.orange,
),
DesktopPanelHeader(title: l10n.combatLog),
Expanded(flex: 2, child: CombatLog(entries: combatLogEntries)),
],
),
);
}
}
/// 인벤토리 목록 위젯
class _InventoryList extends StatelessWidget {
const _InventoryList({required this.state});
final GameState state;
@override
Widget build(BuildContext context) {
final l10n = L10n.of(context);
if (state.inventory.items.isEmpty) {
return Center(
child: Text(
l10n.goldAmount(state.inventory.gold),
style: const TextStyle(
fontFamily: 'PressStart2P',
fontSize: 14,
color: RetroColors.gold,
),
),
);
}
return ListView.builder(
itemCount: state.inventory.items.length + 1,
padding: const EdgeInsets.symmetric(horizontal: 8),
itemBuilder: (context, index) {
if (index == 0) {
return _buildGoldRow(l10n);
}
return _buildItemRow(context, state.inventory.items[index - 1]);
},
);
}
Widget _buildGoldRow(L10n l10n) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 2),
child: Row(
children: [
const Icon(
Icons.monetization_on,
size: 10,
color: RetroColors.gold,
),
const SizedBox(width: 4),
Expanded(
child: Text(
l10n.gold.toUpperCase(),
style: const TextStyle(
fontFamily: 'PressStart2P',
fontSize: 13,
color: RetroColors.gold,
),
),
),
Text(
'${state.inventory.gold}',
style: const TextStyle(
fontFamily: 'PressStart2P',
fontSize: 14,
color: RetroColors.gold,
),
),
],
),
);
}
Widget _buildItemRow(BuildContext context, InventoryEntry item) {
final translatedName = GameDataL10n.translateItemString(
context,
item.name,
);
return Padding(
padding: const EdgeInsets.symmetric(vertical: 1),
child: Row(
children: [
Expanded(
child: Text(
translatedName,
style: const TextStyle(
fontFamily: 'PressStart2P',
fontSize: 13,
color: RetroColors.textLight,
),
overflow: TextOverflow.ellipsis,
),
),
Text(
'${item.count}',
style: const TextStyle(
fontFamily: 'PressStart2P',
fontSize: 13,
color: RetroColors.cream,
),
),
],
),
);
}
}