import 'package:flutter/material.dart'; import 'package:asciineverdie/src/shared/retro_colors.dart'; import 'package:asciineverdie/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, this.titleWidget, }) : assert( title == null || titleWidget == null, 'title과 titleWidget 중 하나만 사용 가능', ); /// 패널 내부 컨텐츠 final Widget child; /// 내부 패딩 final EdgeInsets padding; /// 배경 색상 final Color backgroundColor; /// 테두리 두께 final double borderWidth; /// 골드 테두리 사용 여부 (중요한 패널에 사용) final bool useGoldBorder; /// 패널 타이틀 (상단에 표시) final String? title; /// 커스텀 타이틀 위젯 (title 대신 사용) final Widget? titleWidget; @override Widget build(BuildContext context) { final painter = useGoldBorder ? GoldBorderPainter( borderWidth: borderWidth, fillColor: backgroundColor, ) : PixelBorderPainter( borderWidth: borderWidth, fillColor: backgroundColor, ); final hasTitle = title != null || titleWidget != null; return CustomPaint( painter: painter, child: Padding( padding: EdgeInsets.all(borderWidth).add(padding), child: hasTitle ? Column( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.min, children: [ if (titleWidget != null) _PanelTitleContainer( useGoldBorder: useGoldBorder, child: titleWidget!, ) else _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 _PanelTitleContainer( useGoldBorder: useGoldBorder, child: Text( title.toUpperCase(), style: TextStyle( fontFamily: 'PressStart2P', fontSize: 14, color: useGoldBorder ? RetroColors.gold : RetroColors.textLight, letterSpacing: 1, ), ), ); } } /// 패널 타이틀 컨테이너 (커스텀 위젯용) class _PanelTitleContainer extends StatelessWidget { const _PanelTitleContainer({ required this.useGoldBorder, required this.child, }); final bool useGoldBorder; final Widget child; @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: child, ); } } /// 골드 테두리 레트로 패널 (중요한 컨텐츠용) class RetroGoldPanel extends StatelessWidget { const RetroGoldPanel({ super.key, required this.child, this.padding = const EdgeInsets.all(12), this.title, this.titleWidget, }) : assert( title == null || titleWidget == null, 'title과 titleWidget 중 하나만 사용 가능', ); final Widget child; final EdgeInsets padding; final String? title; final Widget? titleWidget; @override Widget build(BuildContext context) { return RetroPanel( useGoldBorder: true, padding: padding, title: title, titleWidget: titleWidget, child: child, ); } }