feat(ui): 레트로 UI 시스템 추가
- PressStart2P 픽셀 폰트 추가 - RetroColors: 레트로 RPG 스타일 색상 팔레트 - RetroPanel: 픽셀 테두리 패널 위젯 - RetroButton: 레트로 스타일 버튼 - RetroProgressBar: 픽셀 스타일 진행 바 - PixelBorderPainter: 커스텀 테두리 페인터
This commit is contained in:
120
lib/src/shared/widgets/retro_panel.dart
Normal file
120
lib/src/shared/widgets/retro_panel.dart
Normal file
@@ -0,0 +1,120 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:askiineverdie/src/shared/retro_colors.dart';
|
||||
import 'package:askiineverdie/src/shared/widgets/pixel_border_painter.dart';
|
||||
|
||||
/// 레트로 RPG 스타일 패널
|
||||
/// 8-bit 게임의 UI 프레임 느낌을 재현
|
||||
class RetroPanel extends StatelessWidget {
|
||||
const RetroPanel({
|
||||
super.key,
|
||||
required this.child,
|
||||
this.padding = const EdgeInsets.all(12),
|
||||
this.backgroundColor = RetroColors.panelBg,
|
||||
this.borderWidth = 3.0,
|
||||
this.useGoldBorder = false,
|
||||
this.title,
|
||||
});
|
||||
|
||||
/// 패널 내부 컨텐츠
|
||||
final Widget child;
|
||||
|
||||
/// 내부 패딩
|
||||
final EdgeInsets padding;
|
||||
|
||||
/// 배경 색상
|
||||
final Color backgroundColor;
|
||||
|
||||
/// 테두리 두께
|
||||
final double borderWidth;
|
||||
|
||||
/// 골드 테두리 사용 여부 (중요한 패널에 사용)
|
||||
final bool useGoldBorder;
|
||||
|
||||
/// 패널 타이틀 (상단에 표시)
|
||||
final String? title;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final painter = useGoldBorder
|
||||
? GoldBorderPainter(borderWidth: borderWidth, fillColor: backgroundColor)
|
||||
: PixelBorderPainter(borderWidth: borderWidth, fillColor: backgroundColor);
|
||||
|
||||
return CustomPaint(
|
||||
painter: painter,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(borderWidth).add(padding),
|
||||
child: title != null
|
||||
? Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_PanelTitle(title: title!, useGoldBorder: useGoldBorder),
|
||||
const SizedBox(height: 8),
|
||||
Flexible(child: child),
|
||||
],
|
||||
)
|
||||
: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 패널 타이틀 위젯
|
||||
class _PanelTitle extends StatelessWidget {
|
||||
const _PanelTitle({required this.title, required this.useGoldBorder});
|
||||
|
||||
final String title;
|
||||
final bool useGoldBorder;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: useGoldBorder
|
||||
? RetroColors.goldDark.withValues(alpha: 0.3)
|
||||
: RetroColors.panelBorderOuter.withValues(alpha: 0.5),
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: useGoldBorder ? RetroColors.gold : RetroColors.panelBorderInner,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
title.toUpperCase(),
|
||||
style: TextStyle(
|
||||
fontFamily: 'PressStart2P',
|
||||
fontSize: 10,
|
||||
color: useGoldBorder ? RetroColors.gold : RetroColors.textLight,
|
||||
letterSpacing: 1,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 골드 테두리 레트로 패널 (중요한 컨텐츠용)
|
||||
class RetroGoldPanel extends StatelessWidget {
|
||||
const RetroGoldPanel({
|
||||
super.key,
|
||||
required this.child,
|
||||
this.padding = const EdgeInsets.all(12),
|
||||
this.title,
|
||||
});
|
||||
|
||||
final Widget child;
|
||||
final EdgeInsets padding;
|
||||
final String? title;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RetroPanel(
|
||||
useGoldBorder: true,
|
||||
padding: padding,
|
||||
title: title,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user