feat(front): 프론트 화면 개선 및 설정 저장소 추가
- front_screen_animation.dart: 프론트 화면 애니메이션 추가 - settings_repository.dart: 설정 저장소 구현 - front/widgets/: 프론트 화면 위젯 분리 - mobile_carousel_layout.dart: 모바일 레이아웃 개선 - app.dart: 앱 설정 개선 - game_text_l10n.dart: 텍스트 추가
This commit is contained in:
@@ -28,6 +28,8 @@ class NewCharacterScreen extends StatefulWidget {
|
||||
|
||||
class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
final TextEditingController _nameController = TextEditingController();
|
||||
final ScrollController _raceScrollController = ScrollController();
|
||||
final ScrollController _klassScrollController = ScrollController();
|
||||
|
||||
// 종족(races)과 직업(klasses) 목록 (Phase 5)
|
||||
final List<RaceTraits> _races = RaceData.all;
|
||||
@@ -74,14 +76,47 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
|
||||
// 초기 이름 생성
|
||||
_nameController.text = generateName(_nameRng);
|
||||
|
||||
// 선택된 종족/직업으로 스크롤
|
||||
_scrollToSelectedItems();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_nameController.dispose();
|
||||
_raceScrollController.dispose();
|
||||
_klassScrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/// 선택된 종족/직업 위치로 스크롤
|
||||
void _scrollToSelectedItems() {
|
||||
// ListTile 높이 약 48px (dense 모드)
|
||||
const itemHeight = 48.0;
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (_raceScrollController.hasClients) {
|
||||
final raceOffset = _selectedRaceIndex * itemHeight;
|
||||
_raceScrollController.animateTo(
|
||||
raceOffset.clamp(0.0, _raceScrollController.position.maxScrollExtent),
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeOut,
|
||||
);
|
||||
}
|
||||
if (_klassScrollController.hasClients) {
|
||||
final klassOffset = _selectedKlassIndex * itemHeight;
|
||||
_klassScrollController.animateTo(
|
||||
klassOffset.clamp(
|
||||
0.0,
|
||||
_klassScrollController.position.maxScrollExtent,
|
||||
),
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeOut,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// 스탯 굴림 (3d6 × 6)
|
||||
void _rollStats() {
|
||||
final rng = DeterministicRandom(_currentSeed);
|
||||
@@ -108,6 +143,9 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
// 새 시드로 굴림
|
||||
_currentSeed = math.Random().nextInt(0x7FFFFFFF);
|
||||
_rollStats();
|
||||
|
||||
// 선택된 종족/직업으로 스크롤
|
||||
_scrollToSelectedItems();
|
||||
}
|
||||
|
||||
/// Unroll 버튼 클릭 (이전 롤로 복원)
|
||||
@@ -415,6 +453,7 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
SizedBox(
|
||||
height: 300,
|
||||
child: ListView.builder(
|
||||
controller: _raceScrollController,
|
||||
itemCount: _races.length,
|
||||
itemBuilder: (context, index) {
|
||||
final isSelected = index == _selectedRaceIndex;
|
||||
@@ -521,6 +560,7 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
SizedBox(
|
||||
height: 300,
|
||||
child: ListView.builder(
|
||||
controller: _klassScrollController,
|
||||
itemCount: _klasses.length,
|
||||
itemBuilder: (context, index) {
|
||||
final isSelected = index == _selectedKlassIndex;
|
||||
|
||||
Reference in New Issue
Block a user