quel-est-ce-pokemon/lib/presentation/widgets/guess/guess_input_section.dart
Maxiwere45 cb9e214aa2 refactor(guess): split guess_page into focused sub-widgets (<150 lines)
Extract GuessSilhouette, GenFilterSection, LivesRow, GuessInputSection,
ScoreBoard and a shared ScanlineOverlay. guess_page.dart 440 -> 149 lines.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 11:44:55 +02:00

137 lines
4.8 KiB
Dart

import 'package:flutter/material.dart';
/// Section de saisie : indice optionnel, champ de réponse et boutons d'action
/// (Guess / Continue / Hint / Skip). Purement présentationnelle : tout passe par les callbacks.
class GuessInputSection extends StatelessWidget {
final TextEditingController controller;
final String pokemonName;
final bool isHintUsed;
final bool isGuessed;
final int hints;
final int skips;
final VoidCallback onGuess;
final VoidCallback onContinue;
final VoidCallback? onHint;
final VoidCallback? onSkip;
const GuessInputSection({
super.key,
required this.controller,
required this.pokemonName,
required this.isHintUsed,
required this.isGuessed,
required this.hints,
required this.skips,
required this.onGuess,
required this.onContinue,
required this.onHint,
required this.onSkip,
});
/// Masque le nom en ne laissant visibles que la première et la dernière lettre.
String _maskedName(String name) {
if (name.length <= 2) return name; // trop court pour masquer utilement
return '${name[0]}${List.filled(name.length - 2, '_').join()}${name[name.length - 1]}';
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"IDENTIFICATION INPUT",
style: TextStyle(color: Colors.black54, fontSize: 12, fontWeight: FontWeight.bold),
),
const SizedBox(height: 4),
if (isHintUsed)
Container(
width: double.infinity,
margin: const EdgeInsets.only(bottom: 12),
padding: const EdgeInsets.symmetric(vertical: 12),
decoration: BoxDecoration(
color: Colors.amber[100],
border: Border.all(color: Colors.amber[600]!, width: 2),
borderRadius: BorderRadius.circular(8),
),
child: Text(
"HINT: ${_maskedName(pokemonName)}",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: Colors.amber[900], letterSpacing: 4),
),
),
Container(
decoration: BoxDecoration(color: Colors.white, border: Border.all(color: Colors.grey[400]!)),
child: TextField(
controller: controller,
style: const TextStyle(fontSize: 24, letterSpacing: 1.5),
decoration: const InputDecoration(
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
border: InputBorder.none,
hintText: 'Enter Pokémon name...',
),
onSubmitted: (_) => onGuess(),
),
),
const SizedBox(height: 16),
if (isGuessed)
_bigButton(label: "CONTINUE", color: Colors.green, onPressed: onContinue)
else ...[
_bigButton(label: "GUESS!", color: const Color(0xFF3B6EE3), onPressed: onGuess),
const SizedBox(height: 16),
Row(
children: [
Expanded(
child: _actionButton(icon: Icons.lightbulb, label: "HINT ($hints)", color: Colors.amber, onPressed: onHint),
),
const SizedBox(width: 8),
Expanded(
child: _actionButton(icon: Icons.skip_next, label: "SKIP ($skips)", color: Colors.grey[400]!, onPressed: onSkip),
),
],
),
],
],
),
);
}
Widget _bigButton({required String label, required Color color, required VoidCallback onPressed}) {
return SizedBox(
width: double.infinity,
height: 60,
child: ElevatedButton(
onPressed: onPressed,
style: ElevatedButton.styleFrom(
backgroundColor: color,
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero),
),
child: Text(
label,
style: const TextStyle(fontSize: 24, color: Colors.white, fontWeight: FontWeight.bold, letterSpacing: 2),
),
),
);
}
Widget _actionButton({
required IconData icon,
required String label,
required Color color,
required VoidCallback? onPressed,
}) {
return ElevatedButton.icon(
onPressed: onPressed,
icon: Icon(icon, color: Colors.black87),
label: Text(label, style: const TextStyle(color: Colors.black87, fontWeight: FontWeight.bold, fontSize: 18)),
style: ElevatedButton.styleFrom(
backgroundColor: color,
padding: const EdgeInsets.symmetric(vertical: 16),
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero),
),
);
}
}