3 Boutons PushZone Voir PushZone: Exemple-901-PushZone-Statique-onSelectFunction.ino
Déclaration d'un objet statique, utilisation de onSelectFunction Voir PushZone: Exemple-901-PushZone-Statique-onSelectFunction.ino
Déclaration d'un objet dynamique globale, utilisation de onSelectFunction Voir PushZone: Exemple-902-PushZone-Dynamique-onSelectFunction.ino
Déclaration d'un objet dynamique dans le setup(), utilisation de onSelectFunction Voir PushZone: Exemple-903-PushZone-Dynamique-setup-onSelectFunction.ino
Déclaration d'un objet statique, nouvelle classe Voir PushZone: Exemple-904-PushZone-Statique-Classe.ino.
Déclaration d'un objet dynamique globale, nouvelle classe Voir PushZone: Exemple-905-PushZone-Dynamique-Classe.ino
Déclaration d'un objet dynamique dans le setup(), nouvelle classe Voir PushZone: Exemple-906-PushZone-Dynamique-setup-Classe.ino
Déclaration d'un objet dynamique dans le setup() sans pointeur, nouvelle classe Voir PushZone: Exemple-907-PushZone-SansPointeur-Classe.ino
Dans les exemples qui suivent trois boutons sont placées à droite de l'écran. Comme ce sont des
boutons invisibles, un rectangle vert indique leur zone d'action. Leur activité est montré par un
disque blanc (si le bouton est actif) ou sans rien (si le bouton est inactif). Les carrés sont
dessinés d'un côté et les boutons PushZone ayant les mêmes coordonnées récupère l'inforlation
de l'appui. C'est un exemple typique du dessin et du bouton séparé. Il y a plusieurs implantations
possibles, la plus simple est la première version, que l'on utilisera le plus souvent. Pour ce bouton,
je donne toutes les possibiltés, mais pour les autres contrôles, je ne le ferai pas systématiquement.
Toutes les possibiltés sont aussi donné pour Clock.
Quand on appuie sur le bouton, soit la fonction pointée par onSelectFunction est appelée, soit
onSelect() qui est surchargée fait le travail.
Premier exemple: déclaration statique
C'est la façon la plus simple d'utiliser un bouton. L'instance est statique.
PecheuxGraph.zip\PecheuxGraph\examples\Documentation\Exemple-901-PushZone-Statique-onSelectFunction\Exemple-901-PushZone-Statique-onSelectFunction.ino (dans votre fichier téléchargé):
// Mise em place de 3 bouton de type PushZone (pousoir sur une zone, pas de
// dessin dans le bouton). Quand on appuie sur un bouton, un disque blanc
// montre son activité
// Version 1:
// - Les boutons ont une définition statique
// - Utilise onSelectFunction pour exécuter l'action à faire
#include <PecheuxGraph.h> // Appel de la bibliothèque
// Déclaration statique de l'instance, doit se faire en dehors du setup
// Dans ce cas le bouton est accessible partout
PushZone boutonHaut(200, 40, 240, 80); // Bouton en haut
PushZone boutonCentre(200, 100, 240, 140); // Bouton au centre
PushZone boutonBas(200, 160, 240, 200); // Bouton en bas
// Déclaration d'une fonction qui fera ce qu'il faut faire à chaque changement
// Cette fonction ne doit pas avoir de paramètres et ne doit rien retourner
// Le nom peut être quelconque
// Je passe par les pointeurs exceptionnellement pour s'affranchir des noms des
// boutons. Cela permet aussi de montrer l'utilité du pointeru premeirControle.
// Si cela vous pose problème, laissez de côté la compréhension de cette fonction
void Action() // Action à faire quand on appuie sur un bouton
{
PushZone *pointeur = premierControle;
int ordonnee = 180; // Ligne ou se trouve le contrôle. On commence par celui du bas, c'est dle dernier défini
while (pointeur != NULL) // tant qu'on a pas fait toute la liste
{
if (pointeur->isSelected()) fillCircle(100, ordonnee, 20, WHITE); // Disque blanc si il est sélectionné
else fillCircle(100, ordonnee, 20, BLACK);
pointeur = pointeur->controleSuivant; // mise à jour pour le bouton suivant
ordonnee -= 60;
}
}
void setup()
{
setGraphMode(PAYSAGE); // Initialisation de la carte
rect(200, 40, 240, 80, GREEN); // Carré du haut
rect(200, 100, 240, 140, GREEN); // Carré au centre de l'écran
rect(200, 160, 240, 200, GREEN); // Carré du bas
text(F("Appuyez sur un carré"));
boutonHaut.onSelectFunction = &Action; // Fonction appelée si on active le bouton du haut de l'écran
boutonCentre.onSelectFunction = &Action; // Fonction appelée si on active le bouton au milieu de l'écran
boutonBas.onSelectFunction = &Action; // Fonction appelée si on active le bouton en bas de l'écran
boutonHaut.onUnselectFunction = &Action; // Fonction appelée si on désactive le bouton du haut de l'écran
boutonCentre.onUnselectFunction = &Action; // Fonction appelée si on désactive le bouton au milieu de l'écran
boutonBas.onUnselectFunction = &Action; // Fonction appelée si on désactive le bouton en bas de l'écran
}
void loop()
{
scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans le loop
}
Deuxième exemple: déclaration dynamique avant le setup.
Quand on déclare l'instance, on obtient un pointeur sur bouton. Ce pointeur va nous permettre
de modifier ses caractéristiques, notamment le poniteur onSelectFunction.
La déclaration est faite ici avant le setup
PecheuxGraph.zip\PecheuxGraph\examples\Documentation\Exemple-902-PushZone-Dynamique-onSelectFunction\Exemple-902-PushZone-Dynamique-onSelectFunction.ino (dans votre fichier téléchargé):
// Mise em place de 3 bouton de type PushZone (pousoir sur une zone, pas de
// dessin dans le bouton). Quand on appuie sur un bouton, un disque blanc
// montre son activité
// Version 2:
// - Les boutons ont une définition dynamique avant le setup()
// - Utilise onSelectFunction pour exécuter l'action à faire
#include <PecheuxGraph.h> // Appel de la bibliothèque
// Déclaration dynamique de l'instance, peut se faire en dehors du setup
// Dans ce cas bouton est accessible partout
PushZone *boutonHaut = new PushZone(200, 40, 240, 80); // Bouton en haut
PushZone *boutonCentre = new PushZone(200, 100, 240, 140); // Bouton au centre
PushZone *boutonBas = new PushZone(200, 160, 240, 200); // Bouton en bas
// Déclaration d'une fonction qui fera ce qu'il faut faire à chaque changement
// Cette fonction ne doit pas avoir de paramètres et ne doit rien retourner
// Le nom peut être quelconque
// Je passe par les pointeurs exceptionnellement pour s'affranchir des noms des
// boutons. Cela permet aussi de montrer l'utilité du pointeru premeirControle.
// Si cela vous pose problème, laissez de côté la compréhension de cette fonction
void Action() // Action à faire quand on appuie sur un bouton
{
PushZone *pointeur = premierControle;
int ordonnee = 180; // Ligne ou se trouve le contrôle. On commence par celui du bas, c'est dle dernier défini
while (pointeur != NULL) // tant qu'on a pas fait toute la liste
{
if (pointeur->isSelected()) fillCircle(100, ordonnee, 20, WHITE); // Disque blanc si il est sélectionné
else fillCircle(100, ordonnee, 20, BLACK);
pointeur = pointeur->controleSuivant; // mise à jour pour le bouton suivant
ordonnee -= 60;
}
}
void setup()
{
setGraphMode(PAYSAGE); // Initialisation de la carte
rect(200, 40, 240, 80, GREEN); // Carré du haut
rect(200, 100, 240, 140, GREEN); // Carré au centre de l'écran
rect(200, 160, 240, 200, GREEN); // Carré du bas
text(F("Appuyez sur un carré"));
// Association de la fonction qui va faire le travail avec le bouton
// Attention, il y a un caractère "&" avant le nom de la fonction.
// Cette ligne veut dire: bouton a une propriété onSelectFunction et on va
// affecter cette propriété avec l'adresse (présence du "&") de onSelectAction
boutonHaut->onSelectFunction = &Action; // Fonction appelée si on active le bouton du haut de l'écran
boutonCentre->onSelectFunction = &Action; // Fonction appelée si on active le bouton au milieu de l'écran
boutonBas->onSelectFunction = &Action; // Fonction appelée si on active le bouton en bas de l'écran
boutonHaut->onUnselectFunction = &Action; // Fonction appelée si on désactive le bouton du haut de l'écran
boutonCentre->onUnselectFunction = &Action; // Fonction appelée si on désactive le bouton au milieu de l'écran
boutonBas->onUnselectFunction = &Action; // Fonction appelée si on désactive le bouton en bas de l'écran
}
void loop()
{
scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans le loop
}
Troisième exemple: déclaration dynamique dans le setup.
C'est pratiquement la même chose que dans l'exemple précédent, mais l'instance est déclarée dans
le setup. Dans ce cas, l'instance est dans la pile et est accessible tout le temps, mais seul le
pointeur est détruit au sortir du setup. Ou pourrait aussi sur le même principe déclarer l'instance
dans une fonction.
Même si le pointeur est détruit au sortir de la fonction, pendant qu'il exixte, on peut accéder
à l'objet. Cela permet en particuler d'utiliser une boucle pour définir plusieurs objets semblables
dans le style: PushZone *bouton;
for (byte numero=0; numero<10; numero++)
{
bouton = new PushZone(100, 20*numero, 120, 20*numero+20); // Déclaration d'un bouton
bouton->onSelectFunction=&onSelectAction; // Fonction à appeler
}
Ceci crérait 10 boutons les uns en dessous des autres, avec une même action. onSelectAction peut agir en
fonction du bouton par exemple en regardant ou est le stylet grâce à getTouchY().
PecheuxGraph.zip\PecheuxGraph\examples\Documentation\Exemple-903-PushZone-Dynamique-setup-onSelectFunction\Exemple-903-PushZone-Dynamique-setup-onSelectFunction.ino (dans votre fichier téléchargé):
// Mise em place de 3 bouton de type PushZone (pousoir sur une zone, pas de
// dessin dans le bouton). Quand on appuie sur un bouton, un disque blanc
// montre son activité
// Version 3:
// - Les boutons ont une définition dynamique dans le setup()
// - Utilise onSelectFunction pour exécuter l'action à faire
#include <PecheuxGraph.h> // Appel de la bibliothèque
// Déclaration d'une fonction qui fera ce qu'il faut faire à chaque changement
// Cette fonction ne doit pas avoir de paramètres et ne doit rien retourner
// Le nom peut être quelconque
// Je passe par les pointeurs exceptionnellement pour s'affranchir des noms des
// boutons. Cela permet aussi de montrer l'utilité du pointeru premeirControle.
// Si cela vous pose problème, laissez de côté la compréhension de cette fonction
void Action() // Action à faire quand on appuie sur un bouton
{
PushZone *pointeur = premierControle;
int ordonnee = 180; // Ligne ou se trouve le contrôle. On commence par celui du bas, c'est dle dernier défini
while (pointeur != NULL) // tant qu'on a pas fait toute la liste
{
if (pointeur->isSelected()) fillCircle(100, ordonnee, 20, WHITE); // Disque blanc si il est sélectionné
else fillCircle(100, ordonnee, 20, BLACK);
pointeur = pointeur->controleSuivant; // mise à jour pour le bouton suivant
ordonnee -= 60;
}
}
void setup()
{
setGraphMode(PAYSAGE); // Initialisation de la carte
rect(200, 40, 240, 80, GREEN); // Carré du haut
rect(200, 100, 240, 140, GREEN); // Carré au centre de l'écran
rect(200, 160, 240, 200, GREEN); // Carré du bas
text(F("Appuyez sur un carré"));
// Déclaration dynamique de l'instance, faite dans une fonction
// Dans ce cas l'instance est accessible partout, mais le pointeur
// boutonX sera détruit en sortant de la fonction (ici du setup())
PushZone *boutonHaut = new PushZone(200, 40, 240, 80); // Bouton en haut
PushZone *boutonCentre = new PushZone(200, 100, 240, 140); // Bouton au centre
PushZone *boutonBas = new PushZone(200, 160, 240, 200); // Bouton en bas
// Association de la fonction qui va faire le travail avec le bouton
// Attention, il y a un caractère "&" avant le nom de la fonction.
// Cette ligne veut dire: bouton a une propriété onSelectFunction et on va
// affecter cette propriété avec l'adresse (présence du "&") de onSelectAction
boutonHaut->onSelectFunction = &Action; // Fonction appelée si on active le bouton du haut de l'écran
boutonCentre->onSelectFunction = &Action; // Fonction appelée si on active le bouton au milieu de l'écran
boutonBas->onSelectFunction = &Action; // Fonction appelée si on active le bouton en bas de l'écran
boutonHaut->onUnselectFunction = &Action; // Fonction appelée si on désactive le bouton du haut de l'écran
boutonCentre->onUnselectFunction = &Action; // Fonction appelée si on désactive le bouton au milieu de l'écran
boutonBas->onUnselectFunction = &Action; // Fonction appelée si on désactive le bouton en bas de l'écran
}
void loop()
{
scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans le loop
}
Quatrième exemple: Surcharge de onSelect, déclaration statique.
Si on a besoin de plusieurs boutons ayant des comportements identiques, on a vu qu'on peut écrire
une fonction externe pour gérer l'appui. Pour chaque bouton, il faudra alors lui associer
cette fonction externe. En définissant une classe fille de PushZone et en surchargeant onSelect(), on
aura plus qu'a déclarer l'instance, la fonction étant dedans. C'est un peu plus lourd, mais le code
peut être plus clair.
Notez que l'on n'a pas besoin d'accéder au bouton un fois défini, le nom de la variable ne nous
sert à rien
PecheuxGraph.zip\PecheuxGraph\examples\Documentation\Exemple-904-PushZone-Statique-Classe\Exemple-904-PushZone-Statique-Classe.ino (dans votre fichier téléchargé):
// Mise em place d'un simple bouton de type PushZone (pousoir sur une zone
// (pas de dessin dans le bouton). Quand on appuie sur ce bouton, le carré au
// centre de l'écran change de couleur
// Version 4:
// - On définir une classe Bouton, dérivée de PushZone, avec le bon comportement
// - Le bouton a une définition statique
// Mise em place de 3 bouton de type PushZone (pousoir sur une zone, pas de
// dessin dans le bouton). Quand on appuie sur un bouton, un disque blanc
// montre son activité
// Version 4:
// - On définir une classe Bouton, dérivée de PushZone, avec le bon comportement
// - Les boutons ont une définition statique
#include <PecheuxGraph.h> // Appel de la bibliothèque
class Bouton: public PushZone // Nouvelle classe pour redéfinir onSelect
{
public:
Bouton(int x1, int y1, int x2, int y2): PushZone(x1, y1, x2, y2) {} // constructeur, on copie la classe mère
virtual void onSelect() // Nouveau comportement si on le sélectionne
{
fillCircle(100, demiY1 * 2 + 20, 20, WHITE);
}
virtual void onUnselect() // Nouveau comportement si on le déselectionne
{
fillCircle(100, demiY1 * 2 + 20, 20, BLACK);
}
}; // Ne pas oublier le ; à la fin de la déclaration d'une classe
// Déclaration statique des instances, doit se faire en dehors du setup
// Si on la définissait dans le setup elle serait détruite au sortir du setup et
// en pariculier lorsque l'on en a besoin (dans le loop).
Bouton boutonHaut(200, 40, 240, 80); // Bouton en haut
Bouton boutonCentre(200, 100, 240, 140); // Bouton au centre
Bouton boutonBas(200, 160, 240, 200); // Bouton en bas
void setup()
{
setGraphMode(PAYSAGE); // Initialisation de la carte
rect(200, 40, 240, 80, GREEN); // Carré du haut
rect(200, 100, 240, 140, GREEN); // Carré au centre de l'écran
rect(200, 160, 240, 200, GREEN); // Carré du bas
text(F("Appuyez sur un carré"));
}
void loop()
{
scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans le loop
}
Cinquième exemple: Surcharge de onSelect, déclaration dynamique.
Si l'on crée une nouvelle classe, il est aussi possible de définir des insances avec des pointeurs.
PecheuxGraph.zip\PecheuxGraph\examples\Documentation\Exemple-905-PushZone-Dynamique-Classe\Exemple-905-PushZone-Dynamique-Classe.ino (dans votre fichier téléchargé):
// Mise em place de 3 bouton de type PushZone (pousoir sur une zone, pas de
// dessin dans le bouton). Quand on appuie sur un bouton, un disque blanc
// montre son activité
// Version 5:
// - On définir une classe Bouton, dérivée de PushZone, avec le bon comportement
// - Les boutons ont une définition dynamique
#include <PecheuxGraph.h> // Appel de la bibliothèque
class Bouton: public PushZone // Nouvelle classe pour redéfinir onSelect
{
public:
Bouton(int x1, int y1, int x2, int y2): PushZone(x1, y1, x2, y2) {} // constructeur, on copie la classe mère
virtual void onSelect() // Nouveau comportement si on le sélectionne
{
fillCircle(100, demiY1 * 2 + 20, 20, WHITE);
}
virtual void onUnselect() // Nouveau comportement si on le déselectionne
{
fillCircle(100, demiY1 * 2 + 20, 20, BLACK);
}
}; // Ne pas oublier le ; à la fin de la déclaration d'une classe
// Déclaration dynamique de l'instance, peut se faire en dehors du setup
// Dans ce cas bouton est accessible partout
Bouton *boutonHaut = new Bouton(200, 40, 240, 80); // Bouton en haut
Bouton *boutonCentre = new Bouton(200, 100, 240, 140); // Bouton au centre
Bouton *boutonBas = new Bouton(200, 160, 240, 200); // Bouton en bas
void setup()
{
setGraphMode(PAYSAGE); // Initialisation de la carte
rect(200, 40, 240, 80, GREEN); // Carré du haut
rect(200, 100, 240, 140, GREEN); // Carré au centre de l'écran
rect(200, 160, 240, 200, GREEN); // Carré du bas
text(F("Appuyez sur un carré"));
}
void loop()
{
scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans le loop
}
Sixième exemple: Surcharge de onSelect, déclaration dynamique dans une fonction.
Comme cela a été fait plus haut, que l'on dérive une nouvelle classe ou pas, on peut créer
l'instance bouton dans une fonction. Comme tout à l'heure, l'instance existe partout, mais le
pointeur bouton n'est accessible que dans la fonction qui l'a définie.
PecheuxGraph.zip\PecheuxGraph\examples\Documentation\Exemple-906-PushZone-Dynamique-setup-Classe\Exemple-906-PushZone-Dynamique-setup-Classe.ino (dans votre fichier téléchargé):
// Mise em place de 3 bouton de type PushZone (pousoir sur une zone, pas de
// dessin dans le bouton). Quand on appuie sur un bouton, un disque blanc
// montre son activité
// Version 6:
// - On définir une classe Bouton, dérivée de PushZone, avec le bon comportement
// - Les boutons ont une définition dynamique dans une fonction
#include <PecheuxGraph.h> // Appel de la bibliothèque
class Bouton: public PushZone // Nouvelle classe pour redéfinir onSelect
{
public:
Bouton(int x1, int y1, int x2, int y2): PushZone(x1, y1, x2, y2) {} // constructeur, on copie la classe mère
virtual void onSelect() // Nouveau comportement si on le sélectionne
{
fillCircle(100, demiY1 * 2 + 20, 20, WHITE);
}
virtual void onUnselect() // Nouveau comportement si on le déselectionne
{
fillCircle(100, demiY1 * 2 + 20, 20, BLACK);
}
}; // Ne pas oublier le ; à la fin de la déclaration d'une classe
void setup()
{
setGraphMode(PAYSAGE); // Initialisation de la carte
rect(200, 40, 240, 80, GREEN); // Carré du haut
rect(200, 100, 240, 140, GREEN); // Carré au centre de l'écran
rect(200, 160, 240, 200, GREEN); // Carré du bas
text(F("Appuyez sur un carré"));
// Déclaration dynamique de l'instance, peut se faire dans une fonction
// Dans ce cas l'instance est accessible partout, mais le pointeur
// bouton sera détruit en sortant de la fonction (ici du setup())
Bouton *boutonHaut = new Bouton(200, 40, 240, 80); // Bouton en haut
Bouton *boutonCentre = new Bouton(200, 100, 240, 140); // Bouton au centre
Bouton *boutonBas = new Bouton(200, 160, 240, 200); // Bouton en bas
}
void loop()
{
scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans le loop
}
Septième exemple: Surcharge de onSelect, déclaration dynamique dans une fonction, sans pointeur.
Dans la dernière version, on voit que l'on n'a pas besoin du pointeur. Dans ce cas, ce n'est pas la
peine d'en avoir un.
PecheuxGraph.zip\PecheuxGraph\examples\Documentation\Exemple-907-PushZone-SansPointeur-Classe\Exemple-907-PushZone-SansPointeur-Classe.ino (dans votre fichier téléchargé):
// Mise em place de 3 bouton de type PushZone (pousoir sur une zone, pas de
// dessin dans le bouton). Quand on appuie sur un bouton, un disque blanc
// montre son activité
// Version 7:
// - On définir une classe Bouton, dérivée de PushZone, avec le bon comportement
// - Les boutons ont une définition dynamique sans pointeur
#include <PecheuxGraph.h> // Appel de la bibliothèque
class Bouton: public PushZone // Nouvelle classe pour redéfinir onSelect
{
public:
Bouton(int x1, int y1, int x2, int y2): PushZone(x1, y1, x2, y2) {} // constructeur, on copie la classe mère
virtual void onSelect() // Nouveau comportement si on le sélectionne
{
fillCircle(100, demiY1 * 2 + 20, 20, WHITE);
}
virtual void onUnselect() // Nouveau comportement si on le déselectionne
{
fillCircle(100, demiY1 * 2 + 20, 20, BLACK);
}
}; // Ne pas oublier le ; à la fin de la déclaration d'une classe
void setup()
{
setGraphMode(PAYSAGE); // Initialisation de la carte
rect(200, 40, 240, 80, GREEN); // Carré du haut
rect(200, 100, 240, 140, GREEN); // Carré au centre de l'écran
rect(200, 160, 240, 200, GREEN); // Carré du bas
text(F("Appuyez sur un carré"));
// Déclaration dynamique de l'instance, mais on n'a pas besoin du pointeur
// On peut donc créer une instance sans avoir une référence.
new Bouton(200, 40, 240, 80); // Bouton en haut
new Bouton(200, 100, 240, 140); // Bouton au centre
new Bouton(200, 160, 240, 200); // Bouton en bas
}
void loop()
{
scanEvent(); // Gestion des boutons et des horloges, le plus souvent seul dans le loop
}
Voir aussi:
- scanEvent(); Moteur de la gestion des évènements
- pourBoutonTexte("texte"); Aide pour dessiner des boutons textes
- PushCoche; Bouton poussoir case à cocher
- PushCircle; Bouton poussoir rond
- CheckZone; Bouton bistable (va vient) sans dessin
- RadioZone; Bouton radio (un seul bouton actif parmi plusieurs) sans dessin
|