He visto lo que has hecho y me parece un buen trabajo. Aún así, a modo de sugerencia y a ver qué te parecen, le he hecho algunas modificaciones, según mi criterio, que paso a detallar.
No utilizo el IDE de Arduino y mi compilador es un poco puntilloso por lo que no permite usar una función sin haber sido declarado antes. Es por ello he declarado la existencia de algunas de ellas antes de la implementación de las funciones en Pruebas_TFT_LCD.ino. Declararlas es decir que existe una función con un nombre y características determinadas, sin poner el cuerpo de la función, y ya con ello el compilador sabe de su existencia y cómo se ha de invocar, sin necesidad de tener su definición. Definirla es poner la función completa, con su cuerpo.
También he tenido que poner "#include <Adafruit_GFX.h>" en Pruebas_TFT_LCD.ino porque mi compilador es un poco quisquilloso.
Por cuestión de gustos y porque normalmente te encuentras con que sólo empiezan en mayúsculas el nombre de las clases, no el de las variables y funciones, es por lo que me he tomado la licencia de renombrar variables y funciones poniendo en minúscula la primera letra y dejando el resto de la "camellización" de los nombres de la clase (las de Pruebas_TFT_LCD.ino no las he tocado).
El puntero this está disponible en todas las funciones no estáticas de la clase. Apunta al objeto al que pertenece la función que se ha llamado. No es obligatorio (salvo en el caso de ambigüedad por tener una variable local con el mismo nombre). He añadido ese puntero this-> delante de todo uso de funciones o variables de la clase dentro de las funciones de la clase. Así "se ve claro" que es de la clase. Esto permite, aunque no es aconsejable, el uso de parámetros con el mismo nombre que una variable de la clase (sería el que no tiene el this->). También he quitado el guión bajo al inicio de las variables _Pulsado y _tft, ya con el this-> "se ve" que es de la clase (insisto, es cuestión de gustos). Aunque _Pulsado la he renombrado a estaPulsado para que no entre en conflicto con la funcíón pulsado. En el caso de _tft no hay problema en llamarla tft ya que, en el constructor, cuando se utiliza el parámetro tft se diferencian uno de otro porque el parámetro de la función es tft y la variable de la clase es this->tft. Si aún así se prefiere usar el guión bajo, mejor usarlo para todas las variables (por lo menos para las privadas, que deberían ser todas privadas) y no para unas sí y para otras no. Ya cuesta acordarse del nombre, como para encima tener que recordar si llevan guión o no.
DibujarBoton y DibujarBotonPresionado no solo "pierden" la "B" mayúscula, sino que tanbién pierden "Boton". Pasan a llamarse dibujar y dibujarPresionado, no hace falta resaltar que se trata de un botón. Si en lugar de un boton se trata de un icono, las llamaría igual: dibujar o dibujarPresionado. Esto es bastante útil sobre todo si fueras a usar herencia.
Una vez renombradas las funciones y variables de la clase he hecho los siguiente cambios.
El puntero ptrClick pasa a ser una variable privada de la clase. En principio no tiene porqué ser accesible desde fuera de la clase.
Veo que inicializas ptrClick con un NULL en el constructor por defecto y verificas que ptrClick no sea NULL antes de usarlo. En caso de ser NULL no llamas a la función. Pues si acertadamente haces esto con ptrClick deberías de hacer lo mismo con tft. Eso es lo que he hecho, inicializar a NULL tft en el constructor por defecto y verificar que tft no es NULL para no usarlo si lo es. Esto hace que el programa sea más robusto a fallos de programación de quienes usamos la librería.
En lugar de pasar al constructor un puntero a un objeto de la clase Adafruit_TFTLCD (el parámetro tft) lo pasamos por referencia (no es posible en C pero sí en C++) y luego obtenemos su dirección y lo guardamos en la variable tft de la clase (this->tft).
Antes:
Boton::Boton(Adafruit_TFTLCD *tft... // <-- Recibimos un puntero
{
this->tft = tft; // Guardamos ese puntero en la variable de la clase
Ahora:
Boton::Boton(Adafruit_TFTLCD &tft... // <-- Cambiamos el * por un & para indicar que lo recibimos por referencia, y no un puntero
{
this->tft = &tft; // <-- Como es una referencia lo que recibimos, debemos obtener su dirección con el operador & y guardar el puntero
Con lo que para usar el constructor no hay que pasar la dirección del objeto Adafruit_TFTLCD, sino el objeto diréctamente. Como ejemplo vemos que la definición que antes era:
botones[0] = Boton(&tft,20, 50, 30, 200, F("SIMULAR CELULA"),NULL);
Ahora "pierde" el & y queda así:
botones[0] = Boton(tft,20, 50, 30, 200, F("SIMULAR CELULA"),NULL);
Nota: si se pasa por referencia (el & al definir el parámetro de la función) no se puede pasar un NULL. Si se quiere poder pasar un NULL de ha de pasar un puntero (el * al definir el parámetro de la función).
He añadido a la clase las funciones setTft y setClick para poder asignar valores a tft y ptrClick si se ha creado el objeto mediante el constructor por defecto.
En lugar de definir dos veces "los colores" lo he pasado a Boton.h con lo que sólo hay que definirlo una única vez. También he cambiado la forma de definirlos, en lugar de usar el #define lo defino como constantes de tipo uint16_t (he visto que las librerías de Adafruit utilizan ese tipo para el color). A la vez las he creado dentro de un "espacio de nombres" para evitar posibles conflictos por si se utilizan esos mismos nombres para otras constantes con diferentes valores. Para más información, como siempre, buscar en Google. Esto no consume ni más ni menos recursos, debería de generar exactamente el mismo binario.
Tras todas las modificaciones sólo he podido verificar que me compila sin errores. Pero no sé si realmente funciona bien, ya que no dispongo del hardware para probarlo.
Como ves, casi todas las modificaciones son "estéticas". No he mirado "más a fondo". Pero si te funciona es que lo más importante ha de estar correcto.
Adjunto ficheros con las modificaciones.
Boton.cpp (5.8 KB)
Boton.h (2.2 KB)
Pruebas_TFT_LCD.ino (4.58 KB)