4 séries de 10 boutons RadioCoche Voir RadioCoche: Exemple-950-RadioCoche.ino
Pour se détendre, petit QCM Voir RadioCoche: Exemple-951-RadioCoche-QCM.ino
Premier exemple: 4 séries de 10 boutons RadioCoche
PecheuxGraph.zip\PecheuxGraph\examples\Documentation\Exemple-950-RadioCoche\Exemple-950-RadioCoche.ino (dans votre fichier téléchargé):
// Ceci montre un exemple d'utilisation de boutons radio
// - avec quatre séries
// - avec des boutons dynamiques trops de boutons pour écrire ssn une boucle!
#include <PecheuxGraph.h>
word valeur; // Ce qui est écrit avec les boutons
void onTimeAffiche(void) // Cette fonction met à jour l'affichage
{
valeur = 0; // Lecture des boutons radio et calcul de la valeur à afficher
for (byte chiffre = 0; chiffre < 4; chiffre++) // 4 chiffres à lire, on commence par les milliers
valeur = (valeur * 10 + (getRadioValeur(chiffre))); // A chaque fois on décale d'un chiffre
fillRect(0, 0, 83, 25, BLACK); // Efface ce qui est nécessaire
setTextCursor(0, 0); // Ecrire toujours au même endroit
text(String(valeur)); // Ecrit la valeur
}
void setup()
{
RadioCoche *radio; // Pointeur sur un bouton, nécessaire pour préselectionner les zéros
Clock *horloge = new Clock(1000); // Pour un rafraîchissement toutes les secondes
horloge->onTimeFunction = &onTimeAffiche; // Pour appeler la fonction d'affichage toutes les secondes
// Initialisations
setGraphMode(PAYSAGE); // Initialisation générale de l'afficheur
setTextCursor(0, 100);
text("Cliquez sur\nles boutons"); // Dire un minimum ce qu'il faut faire
// Création de boutons dynamiques, doit être fait ici après setGraphMode() car on utilise LARGEUR
for (word colonne = 0; colonne < 150; colonne += 40) for (word ligne = 0; ligne < 200; ligne += 20) // Pour avoir une matrice de boutons
{ // Création d'un bouton
// valeur sera 0, 1, 2, ... soit le dernier paramètre ligne/20
radio = new RadioCoche(LARGEUR - 160 + colonne, ligne, LARGEUR - 140 + colonne, ligne + 20, /*parametres =*/ligne / 20, /*groupe =*/colonne / 40); // Zones de 20x20
if (ligne == 0) radio->select(); // Préselection des 0
// Nom du bouton
setTextCursor(LARGEUR - 140 + colonne, ligne + 2);
text(String(ligne / 20)); // Affichage des chiffres 0, 1, 2, 3, ...
}
// Pour avoir un bouton cyan/rouge, pour montrer comment on fait, pour la démo
RadioCoche::buttonColor = CYAN; // Sera vrai pour tous les boutons radio, cela diminue le nombre de données
drawControles(); // Il faut tout dessiner car les contrôles sont définis après setGraphMode()
setTextSize(4); // Pour bien voir le résultat
}
void loop()
{
scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans le loop
}
Deuxième exemple: Petit QCM
PecheuxGraph.zip\PecheuxGraph\examples\Documentation\Exemple-951-RadioCoche-QCM\Exemple-951-RadioCoche-QCM.ino (dans votre fichier téléchargé):
// Ceci montre un exemple d'utilisation de boutons radio avec un gros mélange
// de genre
#include <PecheuxGraph.h>
//#####################################®#####################################
//## RadioPerso ##
//#####################################®#####################################
// On peut dériver une classe, normalement pour changer un comportement
// Definition de la classe RadioPerso pour le bouton 8
class RadioPerso: public RadioZone
{
public:
RadioPerso(int x1, int y1, int x2, int y2): RadioZone(x1, y1, x2, y2, 0, 0) {}
void drawButton(void)
{ // Dessine un disque comme les RadioCircle
word x = demiX1 + demiX2; // se placer au milieu de la zone
word y = demiY1 + demiY2;
fillCircle(x, y, 4, isSelected()? RED : CYAN); // Y tracer un disque de rayon 4
circle(x, y, 5, isSelected()? CYAN : RED); // Et une bordure opposée
}
};
//#####################################®#####################################
//## Définition des boutons ##
//#####################################®#####################################
// bouton1 est un RadioCoche qui en plus devient jaune si il est actif
// bouton2 est un RadioCoche
// bouton3 est un RadioCoche crée avec new dans le setup
// bouton4 est un RadioCircle crée avec new avant le setup
// bouton5 est un RadioCircle
// bouton6 est un RadioCircle qui en plus devient jaune si il est actif
// bouton7 est un RadioZone mais fait croire qu'il est un RadioCircle
// bouton8 est un RadioPerso mais fait aussi croire qu'il est un RadioCircle
// bouton9 est un RadioCoche mais fait aussi croire qu'il est un RadioCircle
RadioCoche bouton1(10, 20, 30, 40);
RadioCoche bouton2(10, 44, 30, 64);
// RadioCoche bouton3(10, 68, 30, 88); // créé dans le setup
RadioCircle *bouton4 = new RadioCircle(10, 92, 30, 112);
RadioCircle bouton5(10, 116, 30, 136);
RadioCircle bouton6(10, 140, 30, 160);
RadioZone bouton7(10, 164, 30, 184);
RadioPerso bouton8(10, 188, 30, 208);
RadioCoche bouton9(10, 212, 30, 232);
//#####################################®#####################################
//## action ##
//#####################################®#####################################
// C'est cette fonction qui est appellée chaque fois que l'on touche à un
// bouton. C'est elle qui gère tout le programme une fois l'affichage terminé
boolean run = true; // bloque scanEvent() quand c'est fini
void action() // Se produit quand on clique sur un bouton radio
{
// getRadioValeur() retourne ici pour l'exemple 0 quel que soit le bouton. Mais
// je peux savoir quel bouton est appyué en analysant l'ordonnée "y" passée
int y = getTouchY();
y = (y + 5) / 24; // N° du bouton 1..9
if (y == 9) // Gagné
{
run = false; // bloque le scanEvent()
clrscr(); // Affiche en gros le mot "Gagné"
setTextSize(5);
setTextCursor(100, 100);
text(F("Gagné"));
}
else // on a appuyé sur une phrase fausse
{
fillRect(35, y * 24 - 3, 319, y * 24 + 18, BLACK); // Efface l'affirmation
setTextColor(RGBcolor(31,50,25)); // On écrira la correction en rouge
setLimites(35, 0, 319, 239); // PushZone du texte; évite d'avoir à utiliser un setTextCursor() après un retour chariot
switch (y) // C'est le n° du bouton
{
case 1:
setTextCursor(35, 22); text(F("Faux: 1 et 2 sont des RadioCoche. Inactif, l'un est gris,\nl'autre noir. Actif 1 devient jaune")); break;
case 2:
setTextCursor(35, 46); text(F("Faux: 5 et 6 sont des RadioCircle et sont nettement de\ncouleur différentes")); break;
case 3:
setTextCursor(35, 70); text(F("Faux: 7 est un RadioZone avec une fonction de dessin\nvia onFunctionSelect()")); break;
case 4:
setTextCursor(35, 94); text(F("Faux: 1 et 9 sont tous deux des RadioCoche, mais 9 a une\nfonction draw externe qui le redessine")); break;
case 5:
setTextCursor(35, 122); text(F("Faux: ici la moitié sont carrés, l'autre moitié ronds")); break;
case 6:
setTextCursor(35, 142); text(F("Faux: ici il n'y a qu'un groupe, mais 2 est RadioCoche, 4\nest RadioCircle, 7 est RadioZone, et 8 vient d'une sous-classe")); break;
case 7:
setTextCursor(35, 172); text(F("Faux: 3 et 4 sont dynamiques, les autres sont statiques")); break;
case 8:
setTextCursor(35, 194); text(F("Faux: ici, n'utilisant pas valeur, tous les boutons on un\nattribut valeur nul")); break;
}
setLimites(); // On peut maintennat dessiner sur tout l'écran (les boutons radios se redessinent quand ils se sélectionnent ou se déselectionnent
}
}
//#####################################®#####################################
//## cercle ##
//#####################################®#####################################
// Les boutons qui se prennent pour un RadioCircle utilisent cette fonction pour se dessiner
void cercle7() // les boutons 7 8 et 9 se dessinent
{
if (bouton7.isSelected())
{
fillRect(15, 169, 25, 179, BLACK); // Efface l'ancien dessin qui ne nous plaît pas
fillCircle(20, 174, 4, RED); // Dessin qui efface éventuellement la coche
circle(20, 174, 5, CYAN); // Et une bordure opposée
action();
}
else
{
fillRect(15, 169, 25, 179, BLACK); // Efface l'ancien dessin qui ne nous plaît pas
fillCircle(20, 174, 4, CYAN); // Dessin qui efface éventuellement la coche
circle(20, 174, 5, RED); // Et une bordure opposée
}
}
void cercle8() // les boutons 7 8 et 9 se dessinent
{
if (bouton8.isSelected())
{
fillRect(15, 193, 25, 203, BLACK); // Efface l'ancien dessin qui ne nous plaît pas
fillCircle(20, 198, 4, RED); // Dessin qui efface éventuellement la coche
circle(20, 198, 5, CYAN); // Et une bordure opposée
action();
}
else
{
fillRect(15, 193, 25, 203, BLACK); // Efface l'ancien dessin qui ne nous plaît pas
fillCircle(20, 198, 4, CYAN); // Dessin qui efface éventuellement la coche
circle(20, 198, 5, RED); // Et une bordure opposée
}
}
void cercle9() // les boutons 7 8 et 9 se dessinent
{
if (bouton9.isSelected())
{
fillRect(15, 216, 25, 227, BLACK); // Efface l'ancien dessin qui ne nous plaît pas
fillCircle(20, 222, 4, RED); // Dessin qui efface éventuellement la coche
circle(20, 222, 5, CYAN); // Et une bordure opposée
action();
}
else
{
fillRect(15, 216, 25, 227, BLACK); // Efface l'ancien dessin qui ne nous plaît pas
fillCircle(20, 222, 4, CYAN); // Dessin qui efface éventuellement la coche
circle(20, 222, 5, RED); // Et une bordure opposée
}
}
//#####################################®#####################################
//## jaunisse ##
//#####################################®#####################################
// Le bouton 1 (RadioCoche) et le bouton 6 (RadioCircle) appelleront jaunisse() une fois dessinés.
// La couleur des autres ne plaisait pas, ils vont être jaune si sélectionnés, noirs sinon.
// On peut donc changer le dessin d'un seul bouton, de plusieurs, de tous.
// Fond noir par défaut, fond jaune si sélectionné
void jaunisse1()
{
if (bouton1.isSelected())
{
fill(20, 30, YELLOW);
action();
}
else fill(20, 30, DARK_GREY);
}
void jaunisse6()
{
if (bouton6.isSelected())
{
fill(20, 150, YELLOW);
action();
}
else fill(20, 150, DARK_GREY);
}
//#####################################®#####################################
//## Setup ##
//#####################################®#####################################
void setup()
{
// Instanciation du bouton 3
RadioCoche *bouton3 = new RadioCoche(10, 68, 30, 89);
// Pour avoir un bouton sélectionné rouge, pour montrer comment on fait, pour la démo
RadioCoche::buttonColor = BLUE;
// Fonctions onSelect() associée
bouton1.onSelectFunction = &jaunisse1; // Ont la jaunisse
bouton1.onUnselectFunction = &jaunisse1;
bouton6.onSelectFunction = &jaunisse6; // Aussi
bouton6.onUnselectFunction = &jaunisse6;
bouton7.onSelectFunction = &cercle7; // Se prend pour un cercle
bouton7.onUnselectFunction = &cercle7;
bouton8.onSelectFunction = &cercle8; // Aussi
bouton8.onUnselectFunction = &cercle8;
bouton9.onSelectFunction = &cercle9; // Aussi
bouton9.onUnselectFunction = &cercle9;
// Pour les autres:
bouton2.onSelectFunction = &action; // La même action pour tous
bouton3->onSelectFunction = &action; // La même action pour tous
bouton4->onSelectFunction = &action; // La même action pour tous
bouton5.onSelectFunction = &action; // La même action pour tous
// Initialisations
Serial.begin(115200);
setGraphMode(PAYSAGE); // Initialisation générale de l'afficheur
setTextCursor(35, 0); text(F("Cochez la bonne réponse")); // Dire un minimum ce qu'il faut faire
setTextKeep(CUT); // Bien pratique pour débugger!
// N° des boutons ou des questions
setTextCursor(0, 25); text("1");
setTextCursor(0, 49); text("2");
setTextCursor(0, 73); text("3");
setTextCursor(0, 97); text("4");
setTextCursor(0, 121); text("5");
setTextCursor(0, 145); text("6");
setTextCursor(0, 169); text("7");
setTextCursor(0, 193); text("8");
setTextCursor(0, 217); text("9");
// Questions
setTextSize(1); setLimites(35, 0, 319, 239); // Pour avoir de bon retours à la ligne
setTextCursor(35, 26); text(F("Tous les boutons RadioCoche ont les mêmes couleurs"));
setTextCursor(35, 50); text(F("Tous les boutons RadioCircle ont les mêmes couleurs"));
setTextCursor(35, 70); text(F("On ne peut pas utiliser un bouton RadioZone car il ne se\nvoit pas"));
setTextCursor(35, 98); text(F("Tous les boutons RadioCoche ont la même forme"));
setTextCursor(35, 118); text(F("Tous les boutons Radio d'un même groupe doivent avoir\n le même dessin"));
setTextCursor(35, 142); text(F("On ne peut pas avoir dans un même groupe un bouton\nZoneRadio, un bouton RadioCoche et un bouton RadioCircle"));
setTextCursor(35, 166); text(F("On en peut pas dans un même groupe avoir un bouton\nstatique et un bouton dynamique (déclaré par new()"));
setTextCursor(35, 194); text(F("Deux boutons Radio doivent avoir des valeurs différentes\n(dernier paramètre)"));
setTextCursor(35, 218); text(F("Toutes les affirmations au dessus sont fausses"));
setLimites();
// drawControles(); // Inutilse si on déclare les boutons avant setGraphMode()
bouton1.unselect(); // active sa jaunisse;
bouton6.unselect(); // active sa jaunisse;
bouton7.unselect(); // active son cercle;
bouton8.unselect(); // active son cercle;
bouton9.unselect(); // active son cercle;
}
void loop()
{
if (run) scanEvent(); // Agit si on appuie sur l'écran, ne fera plus rien quand run deviendra faux
}
Voir aussi:
- unselectRadio() Déselectionne tous les boutons radios d'un groupe
- getRadioValeur() Donne la valeur du contrôle actif du groupe
- getRadioPointeur() retourne l'adresse du contrôle actif
- scanEvent(); Moteur de la gestion des évènements
- RadioZone; Bouton radio (un seul bouton actif parmi plusieurs) sans dessin
- RadioCircle; Bouton radio (un seul bouton actif parmi plusieurs) rond
- PushCoche; Bouton poussoir case à cocher
- CheckCoche; Bouton bistable (va vient) case à cocher
|