- 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 경로 업데이트
169 lines
4.9 KiB
Dart
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,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|