PushZone

Définition Utilisation Exemple Côté technique
 

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