Pantalla de juego completamente funcional: Pantalla de pausa, victoria, derrota,…

Pantalla de juego completamente funcional: Pantalla de pausa, victoria, derrota, pistas, reinicio y cambio de mano implementados
parent b44b4d5e
export 'pista.dart';
\ No newline at end of file
import 'package:flutter/material.dart';
import 'package:peponator/widgets/pista_widget.dart';
class Pista{
static const primos = [3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97];
final ClasePista clase;
final VoidCallback? onPressed;
late final int divisible;
late final String mensaje;
EstadoPista estado = EstadoPista.BLOQUEADO;
Pista ({
required this.clase,
required int numero,
this.onPressed
}) {
if(clase != ClasePista.DIVISIBLE){
divisible = 0;
}
else{
bool found = false;
for(int i = 0; (i<primos.length) && (primos[i]<=numero/2); i++){
if(numero % primos[i] == 0){
divisible = primos[i];
found = true;
break;
}
}
if(!found){
if(numero < 100){
divisible = 1;
}
else{
divisible = -1;
}
}
}
mensaje = _generaPista(numero);
}
String _generaPista(int numero){
switch(this.clase){
case ClasePista.PAR_IMPAR:
if(numero%2 == 0){
return 'El número es par';
}
return 'El número es impar';
case ClasePista.DIVISIBLE:
if(divisible == 1){
return 'El número es primo inferior a 100';
}
if(divisible == -1){
return 'El número NO es divisible entre primos inferiores a 100';
}
return 'El número es divisible entre ${divisible}';
case ClasePista.SUMA_CIFRAS:
int pseudo = numero;
int suma = 0;
while(pseudo > 0){
suma += pseudo%10;
pseudo = (pseudo/10).floor();
}
return 'La suma de las cifras del número da ${suma}';
case ClasePista.NUMERO_CIFRAS:
int div = 10;
int num = 1;
while(numero/div > 1){
num++;
div *= 10;
}
if(num == 1){
return 'El número tiene 1 cifra';
}
return 'El número tiene ${num} cifras';
}
}
bool validarNumero(int adivinar, int numero){
switch(this.clase){
case ClasePista.PAR_IMPAR:
return adivinar%2 == numero%2;
case ClasePista.DIVISIBLE:
if(divisible == 1){
return primos.contains(numero);
}
if(divisible == -1){
for(int i = 0; (i<primos.length) && (primos[i]<=numero/2); i++){
if(numero % primos[i] == 0){
divisible = primos[i];
return false;
}
}
return true;
}
return adivinar%divisible == numero%divisible;
case ClasePista.SUMA_CIFRAS:
int a = adivinar, b = numero;
int sumaA = 0, sumaB = 0;
while(a > 0 && b > 0){
sumaA += a%10;
sumaB += b%10;
a = (a/10).floor();
b = (b/10).floor();
}
return sumaA == sumaB;
case ClasePista.NUMERO_CIFRAS:
int div = 10;
while(adivinar/div > 10){
div *= 10;
}
return (numero/div < 10 && numero/div >= 1);
}
}
Widget createWidget(){
return PistaWidget(
key: Key(this.clase.name),
titulo: this.clase.getTitle(),
mensaje: (estado.desbloqueada())? mensaje : estado.getMensaje(),
fondo: estado.getColorFondo(),
texto: estado.getColorTexto(),
onPressed: (estado == EstadoPista.DISPONIBLE || estado == EstadoPista.CONFIRMACION)? onPressed : null
);
}
}
enum ClasePista {
PAR_IMPAR,
DIVISIBLE,
SUMA_CIFRAS,
NUMERO_CIFRAS;
String getTitle(){
switch(this){
case PAR_IMPAR:
return '¿Es par o impar?';
case DIVISIBLE:
return '¿Entre qué número es divisible?';
case SUMA_CIFRAS:
return '¿Cuál es la suma de sus cifras?';
case NUMERO_CIFRAS:
return '¿Cuántas cifras tiene?';
}
}
}
enum EstadoPista {
BLOQUEADO,
DISPONIBLE,
CONFIRMACION,
DESBLOQUEADO,
CORRECTO,
INCORRECTO;
Color getColorFondo() {
switch(this){
case BLOQUEADO:
return Colors.black87;
case DISPONIBLE:
return Colors.orange;
case CONFIRMACION:
return Colors.yellow;
case DESBLOQUEADO:
return Colors.white;
case CORRECTO:
return Colors.green.shade400;
case INCORRECTO:
return Colors.red;
}
}
Color getColorTexto() {
if(this.index < 1 || this == EstadoPista.INCORRECTO){
return Colors.white;
}
return Colors.black;
}
String getMensaje(){
switch(this){
case BLOQUEADO:
return "PISTA BLOQUEADA";
case DISPONIBLE:
return "PULSA PARA DESBLOQUEAR";
case CONFIRMACION:
return "¿Seguro? Pulsa de nuevo para confirmar";
default:
return "";
}
}
bool desbloqueada(){
return this.index >= EstadoPista.DESBLOQUEADO.index;
}
}
import 'package:flutter/material.dart';
import 'package:peponator/modelo/pista.dart';
import 'package:peponator/widgets/pantalla_pausa.dart';
import 'package:peponator/widgets/peponator_mensaje.dart';
import 'package:peponator/widgets/pista_widget.dart';
import 'dart:math';
import 'package:peponator/widgets/teclado_numerico.dart';
import 'package:peponator/widgets/tu_mensaje.dart';
// TODO: PantallaJuego debería introducirse en una vista PageStorage para almacenar el estado del scrollController
class PantallaJuego extends StatefulWidget {
const PantallaJuego({super.key});
final bool fromHome;
const PantallaJuego({Key? key, required this.fromHome}): super(key: key);
@override
State<PantallaJuego> createState() => _PantallaJuegoState();
......@@ -16,26 +23,84 @@ class _PantallaJuegoState extends State<PantallaJuego> {
late final TextEditingController textController = TextEditingController();
late final ScrollController scrollController = ScrollController();
late final int numeroAdivinar;
late int numeroAdivinar;
late final int maxIntentos;
List<Widget> mensajes = [];
late final List<Widget> pistas = [];
List<Pista> pistas = [];
late int limiteInferior;
late int limiteSuperior;
late bool manoDerecha = true;
int? numeroEscogido;
bool mostrarPistas = false;
late int intentos;
late bool mostrarPistas;
late bool todasPistasBien;
late bool porDesbloquear;
late bool algunaDesbloqueada;
late bool error;
late bool espera;
late bool victoria;
@override
void initState() {
super.initState();
// TODO: Cargar el máximo de intentos
maxIntentos = 21;
_nuevaPartida();
}
void _nuevaPartida(){
Random random = new Random();
setState(() {
textController.clear();
mensajes.clear();
pistas.clear();
limiteInferior = 1;
// TODO: Cargar el límite superior
limiteSuperior = 100;
numeroAdivinar = random.nextInt(limiteSuperior)+limiteInferior;
intentos = 0;
for(int i = 0; i < ClasePista.values.length && i < ((maxIntentos-1)/5).floor(); i++){
pistas.add(Pista(
clase: ClasePista.values[i],
numero: numeroAdivinar,
onPressed: () {
if(pistas[i].estado == EstadoPista.DISPONIBLE){
setState(() {
pistas[i].estado = EstadoPista.CONFIRMACION;
});
}
else if(pistas[i].estado == EstadoPista.CONFIRMACION) {
setState(() {
pistas[i].estado = EstadoPista.DESBLOQUEADO;
});
_actualizarPistas();
}
},
));
}
mensajes.add(PeponatorMensaje(message: "¡Hola! Estoy pensando en un número del ${limiteInferior} al ${limiteSuperior}. ¿Te crees capaz de adivinarlo?"));
mostrarPistas = false;
todasPistasBien = false;
porDesbloquear = false;
algunaDesbloqueada = false;
error = false;
espera = false;
victoria = false;
});
}
@override
......@@ -50,7 +115,7 @@ class _PantallaJuegoState extends State<PantallaJuego> {
left: 0,
child: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height - 400,
height: MediaQuery.of(context).size.height - 420,
child: (mostrarPistas)? _buildVistaPistas() : _buildVistaMensajes()
)
),
......@@ -58,8 +123,30 @@ class _PantallaJuegoState extends State<PantallaJuego> {
top: 0,
right: 10,
child: ElevatedButton(
onPressed: () {
// TODO: Abrir el diálogo
onPressed: () async {
switch(await showDialog<OpcionPausa>(context: context,
builder: (context) {
return PantallaPausa();
}
)) {
case null:
case OpcionPausa.REANUDAR:
break;
case OpcionPausa.CAMBIO_MANO:
setState(() {
manoDerecha = !manoDerecha;
});
break;
case OpcionPausa.NUEVA_PARTIDA:
_nuevaPartida();
break;
case OpcionPausa.CAMBIAR_DIFICULTAD:
// TODO: Handle this case.
break;
case OpcionPausa.SALIR:
// TODO: Handle this case.
break;
}
},
style: ButtonStyle(
elevation: WidgetStatePropertyAll<double>(5.0),
......@@ -83,7 +170,23 @@ class _PantallaJuegoState extends State<PantallaJuego> {
Positioned(
bottom: 0,
left: 0,
child: _buildTeclado()
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: <Color>[
Theme.of(context).colorScheme.surface,
Theme.of(context).colorScheme.surface.withAlpha(0)
],
stops: <double>[
0.97,
1.0
]
)
),
child: (victoria || intentos >= maxIntentos)? _buildPantallaFinal() :_buildTeclado()
)
)
],
)
......@@ -111,13 +214,36 @@ class _PantallaJuegoState extends State<PantallaJuego> {
}
Widget _buildVistaPistas(){
return ListView.builder(
itemBuilder: (context, item) {
return pistas[item];
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(right: 56.0),
child: Text(
'Pistas Especiales',
style: Theme.of(context).textTheme.headlineLarge,
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0, right: 56.0),
child: Text(
'¡Atención! Usarlas quita puntos',
style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontStyle: FontStyle.italic
),
),
),
ListView.builder(
itemBuilder: (context, index) {
return pistas[index].createWidget();
},
controller: scrollController,
itemCount: pistas.length,
shrinkWrap: true,
),
],
),
);
}
......@@ -125,28 +251,7 @@ class _PantallaJuegoState extends State<PantallaJuego> {
final fullWidth = MediaQuery.of(context).size.width;
final fullHeight = 380.0;
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: <Color>[
Theme.of(context).colorScheme.surface,
Theme.of(context).colorScheme.surface.withAlpha(0)
],
stops: <double>[
0.97,
1.0
]
)
),
child: Column(
children: [
SizedBox(
width: fullWidth,
height: fullHeight/4,
child: Row(
children: [
final primeraFila = <Widget>[
SizedBox(
width: fullWidth/4,
child: _buildHintToggleButton()
......@@ -155,14 +260,9 @@ class _PantallaJuegoState extends State<PantallaJuego> {
width: fullWidth*3/4,
child: _buildTextDisplay()
)
],
),
),
SizedBox(
width: fullWidth,
height: fullHeight*3/4,
child: Row(
children: [
];
final segundaFila = <Widget>[
SizedBox(
width: fullWidth/4,
child: _buildBoundsDisplay()
......@@ -173,20 +273,49 @@ class _PantallaJuegoState extends State<PantallaJuego> {
onNumberPress: _onNumberPress,
onBackspacePress: _onBackspacePress,
onEnterPress: _onEnterPress,
invertBackspaceEnter: !manoDerecha,
disableEnter: (numeroEscogido == null || error || espera),
),
)
],
];
return Column(
children: [
SizedBox(
width: fullWidth,
height: fullHeight/4,
child: Row(
children: (manoDerecha)? primeraFila : primeraFila.reversed.toList(),
),
),
SizedBox(
width: fullWidth,
height: fullHeight*3/4,
child: Row(
children: (manoDerecha)? segundaFila : segundaFila.reversed.toList(),
),
)
],
),
);
}
Widget _buildHintToggleButton(){
final onPressed = () => setState(() {
onPressed() {
setState(() {
mostrarPistas = !mostrarPistas;
});;
for(Pista p in pistas){
if(p.estado == EstadoPista.CONFIRMACION){
p.estado = EstadoPista.DISPONIBLE;
}
}
});
}
const icon = Icon(
Icons.lightbulb,
size: 35.0,
);
const style = ButtonStyle(
shape: WidgetStatePropertyAll<OutlinedBorder>(CircleBorder()),
padding: WidgetStatePropertyAll<EdgeInsets>(
......@@ -200,35 +329,60 @@ class _PantallaJuegoState extends State<PantallaJuego> {
)
);
final IconData? badgeIcon;
if(error){
badgeIcon = null;
}
else if(numeroEscogido != null && algunaDesbloqueada){
if(todasPistasBien){
badgeIcon = Icons.check;
}
else{
badgeIcon = Icons.close;
}
}
else{
if(porDesbloquear){
badgeIcon = Icons.priority_high;
}
else{
badgeIcon = null;
}
}
if(mostrarPistas){
return IconButton.filled(
onPressed: onPressed,
style: style,
icon: const Icon(
Icons.lightbulb,
size: 35.0,
),
icon: icon,
);
}
return IconButton(
onPressed: onPressed,
style: style,
icon: Badge(
label: Text(
'!',
style: Theme.of(context).textTheme.titleLarge?.copyWith(
icon: (badgeIcon != null)?
Badge(
label: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Icon(
badgeIcon,
size: 24,
color: Colors.white,
fontWeight: FontWeight.bold
),
),
backgroundColor: Colors.red,
offset: const Offset(16.0, -16.0),
backgroundColor: (numeroEscogido != null && algunaDesbloqueada && todasPistasBien)? Colors.green : Colors.red,
offset: Offset(
manoDerecha? 16.0 : -58.0,
-16.0
),
child: const Icon(
Icons.lightbulb,
size: 35.0,
),
)
) :
icon
);
}
......@@ -241,9 +395,19 @@ class _PantallaJuegoState extends State<PantallaJuego> {
enableInteractiveSelection: false,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleLarge,
decoration: const InputDecoration(
decoration: InputDecoration(
hintText: 'Tu respuesta...',
border: OutlineInputBorder()
border: OutlineInputBorder(),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.red,
width: 5.0
)
),
errorText: error? '' : null,
errorStyle: TextStyle(
fontSize: 0
)
),
),
),
......@@ -256,7 +420,6 @@ class _PantallaJuegoState extends State<PantallaJuego> {
numeroEscogido! <= limiteSuperior &&
numeroEscogido! >= limiteInferior) {
gradient = (1-(numeroEscogido! - limiteInferior)/(limiteSuperior - limiteInferior));
print(gradient);
}
return Column(
......@@ -265,6 +428,39 @@ class _PantallaJuegoState extends State<PantallaJuego> {
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'Intentos',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: Theme.of(context).colorScheme.primary,
fontWeight: FontWeight.bold,
)
),
Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0, top: 8.0),
child: Container(
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
side: BorderSide(
color: Theme.of(context).colorScheme.primary,
width: 3.0
),
borderRadius: BorderRadius.all(Radius.circular(16.0))
)
),
child: Text(
(maxIntentos - intentos).toString(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
),
),
)
]
),
const SizedBox(height: 32.0,),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'Máximo',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
......@@ -347,18 +543,108 @@ class _PantallaJuegoState extends State<PantallaJuego> {
)
),
]
),
],
);
}
Widget _buildPantallaFinal(){
final fullWidth = MediaQuery.of(context).size.width;
final fullHeight = 380.0;
return SizedBox(
width: fullWidth,
height: fullHeight,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Column(
children: [
Text(
victoria? '¡Enhorabuena!' : '¡Sin intentos!',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headlineMedium,
),
const SizedBox(height: 16.0),
Text(
victoria? '¿Quieres jugar otra vez?' : 'Más suerte la próxima vez...',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleLarge,
),
],
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: OpcionesFinPartida.values.map((element) {
final onPressed;
switch(element){
case OpcionesFinPartida.REPETIR:
onPressed = () {
_nuevaPartida();
};
break;
case OpcionesFinPartida.CAMBIAR_DIFICULTAD:
// TODO: Handle this case.
onPressed = () { };
break;
case OpcionesFinPartida.SALIR:
// TODO: Handle this case.
onPressed = () { };
break;
}
return SimpleDialogOption(
child: TextButton.icon(
onPressed: onPressed,
style: TextButton.styleFrom(
side: BorderSide(
color: Colors.black26,
width: 3.0
)
),
icon: Icon(
element.icon,
color: element.color ?? Theme.of(context).colorScheme.primary,
size: 32.0
),
label: Text(
element.text,
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: element.color ?? Theme.of(context).colorScheme.primary
),
),
),
);
}).toList(),
),
)
],
),
),
);
}
void _onNumberPress(int number){
if(!espera){
setState(() {
numeroEscogido ??= 0;
numeroEscogido = numeroEscogido!*10 + number;
if(numeroEscogido == 0) numeroEscogido = null;
textController.text = numeroEscogido?.toString() ?? "";
if(numeroEscogido != null && (numeroEscogido! < limiteInferior || numeroEscogido! > limiteSuperior)){
error = true;
}
else{
error = false;
}
});
_actualizarPistas();
}
}
void _onBackspacePress(){
......@@ -367,22 +653,112 @@ class _PantallaJuegoState extends State<PantallaJuego> {
numeroEscogido = (numeroEscogido!/10).floor();
if(numeroEscogido == 0) numeroEscogido = null;
textController.text = numeroEscogido?.toString() ?? "";
if(numeroEscogido != null && (numeroEscogido! < limiteInferior || numeroEscogido! > limiteSuperior)){
error = true;
}
else{
error = false;
}
});
_actualizarPistas();
}
void _onEnterPress(){
final initialMaxScrollExtent =
scrollController.position.maxScrollExtent;
void _onEnterPress() {
setState(() {
if(numeroEscogido != null && numeroEscogido! >= limiteInferior && numeroEscogido! <= limiteSuperior){
mostrarPistas = false;
mensajes.add(TuMensaje(message: numeroEscogido.toString()));
mensajes.add(PeponatorMensaje(message: "¡Hola! Estoy pensando en un número del ${limiteInferior} al ${limiteSuperior}. ¿Te crees capaz de adivinarlo?"));
numeroEscogido = null;
textController.text = "";
espera = true;
}
});
_escribirRespuesta();
WidgetsBinding.instance.addPostFrameCallback((_) {
_scrollDown();
});
}
void _actualizarPistas(){
setState(() {
if(numeroEscogido == null){
porDesbloquear = false;
}
else{
todasPistasBien = true;
}
});
for(int i = 0; i<pistas.length && i<(intentos/5).floor(); i++){
if(pistas[i].estado == EstadoPista.BLOQUEADO){
setState(() {
porDesbloquear = true;
pistas[i].estado = EstadoPista.DISPONIBLE;
});
}
else if(pistas[i].estado.desbloqueada()){
if(!algunaDesbloqueada) algunaDesbloqueada = true;
if(error || numeroEscogido == null){
setState(() {
pistas[i].estado = EstadoPista.DESBLOQUEADO;
});
}
else{
if(pistas[i].validarNumero(numeroAdivinar, numeroEscogido!)){
setState(() {
pistas[i].estado = EstadoPista.CORRECTO;
});
}
else{
setState(() {
todasPistasBien = false;
pistas[i].estado = EstadoPista.INCORRECTO;
});
}
}
}
else if(!porDesbloquear){
setState(() {
porDesbloquear = true;
});
}
}
}
void _escribirRespuesta() async {
await Future.delayed(Duration(milliseconds: 600));
setState(() {
// TODO: Construir respuesta de Peponator con cierto retardo
mensajes.add(PeponatorMensaje(message: "¡Hola! Estoy pensando en un número del ${limiteInferior} al ${limiteSuperior}. ¿Te crees capaz de adivinarlo?"));
if(numeroEscogido! < numeroAdivinar){
limiteInferior = numeroEscogido!;
}
if(numeroEscogido! > numeroAdivinar){
limiteSuperior = numeroEscogido!;
}
if(numeroEscogido! == numeroAdivinar){
victoria = true;
}
numeroEscogido = null;
intentos++;
espera = false;
});
_actualizarPistas();
WidgetsBinding.instance.addPostFrameCallback((_) {
_scrollDown();
});
}
}
enum OpcionesFinPartida {
REPETIR(Icons.play_arrow_outlined, "Jugar otra vez", Color.fromARGB(255, 0, 125, 0)),
CAMBIAR_DIFICULTAD(Icons.settings_outlined, "Cambiar de dificultad"),
SALIR(Icons.logout, "Volver al inicio", Color.fromARGB(255, 213, 0, 0));
final IconData icon;
final String text;
final Color? color;
const OpcionesFinPartida(this.icon, this.text, [this.color]);
}
......@@ -14,7 +14,7 @@ class PeponatorApp extends StatelessWidget {
),
darkTheme: ThemeData.dark(),
themeMode: ThemeMode.system,
home: PantallaJuego(),
home: PantallaJuego(fromHome: true,),
);
}
}
import 'package:flutter/material.dart';
class PantallaPausa extends StatelessWidget {
const PantallaPausa({Key? key}): super(key: key);
@override
Widget build(BuildContext context) {
return SimpleDialog(
title: Center(child: Text(
'Pausa',
style: Theme.of(context).textTheme.headlineLarge,
)),
children: OpcionPausa.values.map((element) {
return SimpleDialogOption(
child: TextButton.icon(
onPressed: () {
Navigator.pop(context, element);
},
style: TextButton.styleFrom(
side: BorderSide(
color: Colors.black26,
width: 3.0
)
),
icon: Icon(
element.icon,
color: element.color ?? Theme.of(context).colorScheme.primary,
size: 32.0
),
label: Text(
element.text,
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: element.color ?? Theme.of(context).colorScheme.primary
),
),
),
);
}).toList(),
);
}
}
enum OpcionPausa {
REANUDAR(Icons.play_arrow_outlined, "Reanudar", Color.fromARGB(255, 0, 125, 0)),
CAMBIO_MANO(Icons.front_hand_outlined, "Cambiar de mano"),
NUEVA_PARTIDA(Icons.refresh, "Nueva partida"),
CAMBIAR_DIFICULTAD(Icons.settings_outlined, "Cambiar dificultad"),
SALIR(Icons.logout, "Terminar partida", Color.fromARGB(255, 213, 0, 0));
final IconData icon;
final String text;
final Color? color;
const OpcionPausa(this.icon, this.text, [this.color]);
}
\ No newline at end of file
import 'package:flutter/material.dart';
\ No newline at end of file
import 'package:flutter/material.dart';
class PistaWidget extends StatelessWidget {
final String titulo;
final String mensaje;
final Color fondo;
final Color texto;
final VoidCallback? onPressed;
PistaWidget({Key? key, required this.titulo, required this.mensaje, required this.fondo, required this.texto, this.onPressed}):
super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(top: 12.0),
child: Column(
children: [
Text(
titulo,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold
),
),
SizedBox(
width: double.infinity,
child: TextButton(
onPressed: onPressed,
style: TextButton.styleFrom(
backgroundColor: fondo,
),
child: Text(
mensaje,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: texto
),
),
),
),
],
),
);
}
}
......@@ -15,6 +15,9 @@ class TecladoNumerico extends StatelessWidget {
final Color backspaceColor;
final Color enterColor;
final bool invertBackspaceEnter;
final bool disableEnter;
const TecladoNumerico({
Key? key,
this.onNumberPress,
......@@ -26,6 +29,8 @@ class TecladoNumerico extends StatelessWidget {
this.numberColor = const Color.fromARGB(255, 255, 255, 255),
this.backspaceColor = const Color.fromARGB(255, 255, 255, 255),
this.enterColor = const Color.fromARGB(255, 255, 255, 255),
this.invertBackspaceEnter = false,
this.disableEnter = false
}): super(key: key);
@override
......@@ -62,9 +67,9 @@ class TecladoNumerico extends StatelessWidget {
Expanded(
child: Row(
children: [
_buildBackspaceButton(context),
invertBackspaceEnter? _buildEnterButton(context) : _buildBackspaceButton(context),
_buildNumberButton(context, 0),
_buildEnterButton(context)
invertBackspaceEnter? _buildBackspaceButton(context) : _buildEnterButton(context),
],
),
),
......@@ -129,12 +134,12 @@ class TecladoNumerico extends StatelessWidget {
padding: const EdgeInsets.all(8.0),
child: TextButton(
style: TextButton.styleFrom(
backgroundColor: enterBackgroundColor,
backgroundColor: disableEnter? Theme.of(context).disabledColor : enterBackgroundColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(16.0))
)
),
onPressed: onEnterPress,
onPressed: disableEnter? null : onEnterPress,
child: Icon(
Icons.keyboard_return,
color: enterColor,
......
export 'tu_mensaje.dart';
export 'peponator_mensaje.dart';
export 'pista_widget.dart';
export 'teclado_numerico.dart';
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment