Programmation événementielle avec PecheuxGraph

Présentation

Après avoir écrit les fonctions de bas niveau pour mes écrans, c'est à dire les fonctions permettant l'accès aux registres, j'ai écrit les fonctions de base, points, droites... Cela a suivi de fonctions un peu plus évoluées comme les cercles, les textes, les images... Maintenant, je m'attelle à une couche supplémentaire, les horloges et les boutons, le tout en mettant en place une gestion d'événements. Plus les fonctions proposées sont complexes, plus c'est simple d'utilisation, mais plus cela prend de la place dans la mémoire. Une gestion complexe ferait des programmes ne tenant pas dans l'arduino. Si je fais un bouton comme c'est fait sur un OS traditionnel, il ne fonctionnera pas. J'ai donc choisi de limiter au maximum les caractéristiques des objets.

Pour l'instant, les objets gérés par cette partie de la bibliothèque sont quelques boutons et quelques horloges. Il est possible que par la suite, j'ajoute des objets supplémentaires. Si ils ne sont pas utilisés, le code n'est pas gardé à l'édition des liens, et à part rajouter un peu de temps à la compilation, cela ne porte pas préjudice.

 

Organisation de la gestion des événements

Les événements reconnus et traités sont:
- les fins de comptage des horloges
- l'appui avec le stylet (ou avec autre chose) sur l'afficheur
- la sortie du stylet d'un contrôle si il est toujours enfoncé
- le relâchement du stylet

Les objets traités sont de deux sortes:
- les horloges qui ne sont sensibles qu'au premier type d'événement ci-dessus
- les contrôles, que j'appelle ainsi venant des "contrôles graphiques" de windows. Mais certains boutons ne sont pas graphiques, ils n'ont pas de dessin, juste une zone d'action. Mais on peut les dessiner si l'on veut. Ces contrôles sont sensibles aux trois derniers types d'événements.

Même si les deux types d'événements sont séparés, la gestion est très semblable pour tous ces objets. Quand un événement arrive le gestionnaire ou l'objet va traiter cet événement. Sera ensuite appelée une fonction interne à l'objet qui ne fait rien par défaut mais que l'on peut surcharger aisément. Enfin si elle a été définie une fonction externe sera appelée; cela permet simplement de répondre à un événement sans avoir à créer de nouveaux objets.

Pour écrire un programme, il va falloir définir les contrôles (boutons), les horloges ainsi que toutes fonctions qui seront appelées si il se passe des choses. Éventuellement redéfinir de nouvelles classes de boutons ou d'horloges. Il faut aussi initialiser l'application, définir son visuel de départ par exemple, définir les variables...

Pour organiser tout ce petit monde, c'est à dire permettre que les boutons ou les horloges déclenchent les actions voulues, au stylet d'être lu, la fonction scanEvent() va s'en occuper chaque fois qu'elle est appelée. On la mettra bien souvent toute seule, dans la boucle loop().

Un programme type va ressembler à:

#include <PecheuxGraph.h>

### Déclarations des variables globales du programme ###

### Déclarations des fonctions qui seront appelées par les objets  ###

### Déclarations des objets (boutons, horloges...) ###


void setup()
{
  setGraphMode(PAYSAGE); // Initialisation, on a l'habitude!

  ### Liaisons entre les objets et les fonctions à appeler ###
  
  ### Initialisation du programme ###
}

void loop()
{
  scanEvent();
}

Bien entendu, le cadre n'est pas aussi rigide, on peut déclarer les objets dans le setup(), déclarer des fonctions avant ou après les objets... le tout est de respecter les règles du C++, souvent celle qui permet d'utiliser une variable que si elle est définie avant!

Connaître la programmation objet est un plus, et peut aider à comprendre, mais ce n'est pas indispensable (sauf si vous voulez dériver une classe pour en faire une classe fille). Si vous ne connaissez pas la programmation objet, pensez qu'un objet est une super-variable qui contient des données et des fonctions et remplacez les mots:
- "classe" par "type de cette super-variable"
- "propriété" par "donnée de cette super-variable"
- "méthode" par "fonction de cette super-variable".

Pour l'instant il n'est pas possible de détruire un objet (bouton, horloge) en cours de programme. C'est une fonction annexe qui ne consomme pas de code pour celui qui n'utilise pas cette fonctionnalité, que je ferais probablement.

 

Les horloges

Il y a deux types d'horloge:
- Clock: que je traduis par métronome, qui va régulièrement avoir un événement. Toutes les horloges doivent descendre de cette classe
- Timer: que je traduis par temporisateur. Il faut le déclencher et il n'aura alors qu'un seul événement (il est réarmable bien sûr)

 

Les contrôles

Il y a trois sortes de boutons:
- Push: poussoir, comme pour un bouton de sonnette, s'active quand on appui dessus, se désactive quand on le relâche
- Check: case à cocher, qui s'active quand on appuie dessus et qui se désactive quand on appuie à nouveau
- Radio: bouton qui s'active quand on appuie dessus et qui se désactive si un autre bouton radio s'active

Ces catégories se déclinent en trois versions:
- Zone: défini des boutons qui n'ont pas de dessin. On crée un fond par ailleurs et une zone cliquable est définie
- Coche: non sélectionné, c'est une petit carré. Sélectionné, une coche vient se mettre dedans
- Circle: un disque avec un bord voit sa couleur s'inverser quand il est sélectionné.

En combinant les deux, on obtient 9 classes de boutons. Tous les boutons doivent dériver de la classe PushZone

Un bouton, c'est principalement une zone d'action rectangulaire.

 

Utilisation

Il y a plusieurs façons de déclarer les objets. On peut avoir une déclaration statique Clock hologe(); ou dynamique avec new. Les objets dynamiques peuvent être définis dans le setup() ce qui permet d'en définir plusieurs en faisant des boucles. Un des programmes d'illustration comporte 35 métronomes, chacun ayant une fonction associée; il serait fastidieux de les créer en écrivant les 70 lignes!

De même pour utiliser les objets, il y a plusieurs possibilités, on peut utiliser une fonction externe, interroger directement des propriétés ou surcharger une méthode.

Tout cela est détaillé pour les deux objets de base Clock et PushZone.

La page Dessins et boutons "Zone" indique comment utiliser une photo ou un dessin comme canevas pour placer des boutons zone, faire un menu déroulant.

 

Etalonnage du Touchpad   <<     >>   Dessins et boutons Zone