feat(arena): 아레나 전투 화면 및 위젯 개선
- ArenaBattleScreen UI 개선 - 장비 비교 리스트 기능 확장
This commit is contained in:
@@ -9,7 +9,7 @@ import 'package:asciineverdie/src/shared/retro_colors.dart';
|
||||
// 임시 문자열 (추후 l10n으로 이동)
|
||||
const _myEquipmentTitle = 'MY EQUIPMENT';
|
||||
const _enemyEquipmentTitle = 'ENEMY EQUIPMENT';
|
||||
const _selectSlotLabel = 'SELECT';
|
||||
const _selectedLabel = 'SELECTED';
|
||||
const _recommendedLabel = 'BEST';
|
||||
|
||||
/// 좌우 대칭 장비 비교 리스트
|
||||
@@ -50,6 +50,41 @@ class _ArenaEquipmentCompareListState extends State<ArenaEquipmentCompareList> {
|
||||
/// 현재 확장된 슬롯 (탭하여 비교 중인 슬롯)
|
||||
EquipmentSlot? _expandedSlot;
|
||||
|
||||
/// 스크롤 컨트롤러 (자동 스크롤용)
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
|
||||
/// 슬롯별 행 높이 (대략적 계산용)
|
||||
static const double _rowHeight = 40.0;
|
||||
static const double _expandedHeight = 200.0;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/// 선택된 슬롯으로 자동 스크롤
|
||||
void _scrollToSlot(EquipmentSlot slot) {
|
||||
final index = EquipmentSlot.values.indexOf(slot);
|
||||
if (index < 0) return;
|
||||
|
||||
// 현재 확장된 슬롯까지의 높이 계산
|
||||
double targetOffset = 0;
|
||||
for (int i = 0; i < index; i++) {
|
||||
targetOffset += _rowHeight;
|
||||
if (_expandedSlot == EquipmentSlot.values[i]) {
|
||||
targetOffset += _expandedHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// 부드럽게 스크롤
|
||||
_scrollController.animateTo(
|
||||
targetOffset,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeOutCubic,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
@@ -60,6 +95,7 @@ class _ArenaEquipmentCompareListState extends State<ArenaEquipmentCompareList> {
|
||||
// 장비 리스트
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
controller: _scrollController,
|
||||
itemCount: EquipmentSlot.values.length,
|
||||
itemBuilder: (context, index) {
|
||||
final slot = EquipmentSlot.values[index];
|
||||
@@ -137,9 +173,17 @@ class _ArenaEquipmentCompareListState extends State<ArenaEquipmentCompareList> {
|
||||
// 슬롯 행 (좌우 대칭)
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
// 탭하면 즉시 선택 + 확장 + 자동 스크롤
|
||||
widget.onSlotSelected(slot);
|
||||
setState(() {
|
||||
_expandedSlot = isExpanded ? null : slot;
|
||||
});
|
||||
// 확장될 때만 스크롤 (다음 프레임에서 실행)
|
||||
if (!isExpanded) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_scrollToSlot(slot);
|
||||
});
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 4),
|
||||
@@ -393,30 +437,37 @@ class _ArenaEquipmentCompareListState extends State<ArenaEquipmentCompareList> {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
// 선택 버튼
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
widget.onSlotSelected(slot);
|
||||
setState(() => _expandedSlot = null);
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: RetroColors.goldOf(context),
|
||||
foregroundColor: RetroColors.backgroundOf(context),
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
// 선택됨 인디케이터 (SELECT 버튼 대신)
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: RetroColors.goldOf(context).withValues(alpha: 0.2),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
border: Border.all(
|
||||
color: RetroColors.goldOf(context),
|
||||
width: 2,
|
||||
),
|
||||
child: Text(
|
||||
_selectSlotLabel,
|
||||
style: TextStyle(
|
||||
fontFamily: 'PressStart2P',
|
||||
fontSize: 7,
|
||||
color: RetroColors.backgroundOf(context),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.check_circle,
|
||||
color: RetroColors.goldOf(context),
|
||||
size: 16,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
_selectedLabel,
|
||||
style: TextStyle(
|
||||
fontFamily: 'PressStart2P',
|
||||
fontSize: 7,
|
||||
color: RetroColors.goldOf(context),
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user