Go Down

Topic: Tutoriel menu de différentes pages sur un écran TFT avec la librairie utft (Read 342 times) previous topic - next topic

Heloderma-kris

Salut a tous !

Une question revient souvent sur le forum à savoir comment faire un système de plusieurs pages ou menu, sur un écran tactile.
Pré requis :



Variable globale :

Ce qu'il nous faut dans un premier temps, c'est une variable globale au sketch, qui serra ce que j'appellerai un « sélecteur de page ».
Je choisi personnellement de l'appeler :
Code: [Select]
unsigned int selecteurPage=0;//variable de sélection de menu pour l'interface tactile
Je le déclare volontairement sous forme d'un « unsigned int » pour limiter l'impacte sur l'espace mémoire, je n'ai pas pris un « byte » car la méthode du sélecteur de pages repose sur des multiplications par 10 par sous menus. Vous comprendrez pourquoi plus tard ne soyer pas impatient.
Création des Pages :
Maintenant nous devons crée différentes fonctions qui seront en fait les différentes pages de notre système de menu
Ex :
Code: [Select]
void Menu_index(){} ;
void Menu_1(){} ;
void Menu_11(){} ;
void Menu_12(){} ;
void Menu_121(){} ;
void Menu_2(){} ;


Bref voici différente « page » ou « fonction page » dont on pourrait représenter l'arborescence ainsi :



Construction du Menu :

Maintenant que nous avons notre variable « sélecteur de page » et nos « fonctions page », on va crée un système pour que nos pages soit sélectionnées en fonction de la valeur du sélecteur. Pour cela tout va ce passer dans la boucle « loop() » à l'intérieur d'un « Switch » :
Code: [Select]
void loop(){
switch(selecteurPage){
    case 0:
      Menu_Affichage_Principale();
      break;
    case 1:
Menu_1() ;
      break;
    case 11:
Menu_11() ;
      break;
    case 12:
Menu_12() ;
      break;
    case 121:
Menu_121() ;
      break;
    case 2:
Menu_2() ;
      break;
default :
      Menu_Affichage_Principale();
      break;
}}

 
Que va-t-il ce passer dans notre programme :

Et bien a chaque boucle le système va tester la valeur de notre « sélecteur de page » et effectuer la « fonction page » correspondant au cas sélectionné ! Il affichera donc pour chaque cas la « fonction page » correspondante et donc sont contenu.

Détection de l'appui sur une zone :

Ce qu'il nous faut maintenant, c'est une fonction qui détecte l'appui sur une zone précise. La je me suis servi des données trouvées sur le site http://www.mon-club-elec.fr/
Voici la fonction c'est cadeau :
Code: [Select]
boolean TestTouche( int zoneX, int zoneY,int Longueur,int hauteur)
{
   int X, Y,testX,testY; // varriable
  if (myTouch.dataAvailable())// dataAvailable() est une fonction de la lib Utouch.h
    {
        myTouch.read();// read() est une fonction de la lib Utouch.h
        X=myTouch.getX(), Y=myTouch.getY();// getX et getY() sont des fonction de la lib Utouch.h
        //---- vérifie si appui sur la touche "+" ---------
        testX=abs(X-(zoneX+Longueur/2)); // calcul valeur absolue de l'écart de X touchpad à la  Zone X centre touche
        testY=abs(Y-(zoneY+hauteur/2)); // calcul valeur absolue de l'écart de Y touchpad à la  Zone Y centre touche
        if (testX<Longueur/2 && testY<hauteur/2)
         {return true;}
        else
         { return false;}
    }
    return false;
}


Maintenant que nous pouvons détecter l'appui sur une zone on peut alors modifier notre « sélecteur de pages ».

Modification du « sélecteur de pages » :

On va prendre l'exemple de la page d'accueil en imaginant que l'on a créé une interface avec une ou deux zones tactiles.
Code: [Select]
void Menu_Affichage_Principale(){
// Ici on trace affiche ce que l'on veut
// On test s'il y a appuis sur al zone situer au pixel 100,100 //de longueur 50pixel et de hauteur 30pixel
    if (TestTouche( 100, 100,50,30)== true ){
selecteurPage=1;// on sélectionne la nouvelle page à afficher
      return;// on sort de la fonction s'il y'a eu appui
    }
// On test s'il y a appuis sur al zone situer au pixel 200,200 //de longueur 50pixel et de hauteur 30pixel
    if (TestTouche( 200, 200,50,30)== true ){
selecteurPage=2;// on sélectionne la nouvelle page à afficher
      return;// on sort de la fonction s'il y'a eu appui
    }
  return ;
}

 
Gagner du temps de travail et éviter de réafficher :

Notre système est déjà opérationnel en l'état, mais il n'est pas optimiser car il va sans cesse réafficher l'intégralité de nos pages.
En effet pour ceux qui ont déjà essayé lorsque l'on utilise un écran de grande taille (perso des 5") le temps d'affichage peut être très long et qui dit affichage long dit perte de temps pour faire autre chose!
Voici une astuce pour éviter cela et ainsi gagner du temps d'affichage!
On va donc réfléchir et ce demander à chaque pages crées, qu'est ce qui doit être rafraichie à chaque cycle et qu'est ce qui fait partie du décor (statique)! En gros nos variables de mesures, sondes, accelero ..., elles doivent être réaffichées en permanence.
Par contre les titres, les images, les textes... font partie des choses à ne pas réafficher ! L'idée est donc très simple, on va créer une autre variable globale par exemple comme ça:
Code: [Select]
boolean  comptAff= false;// compteur d'affichage permet de ne pas rafraichir en permanence
Puis dans notre page d'exemple, on va à nouveau utiliser un Switch qui va tester notre variable "comptAff"
Code: [Select]
void Menu_Affichage_Principale(){
switch(comptAff){
case 0:
// Ici on trace, affiche, ce que l'on veut:
/// Exemple les zone de nos touches
lcd.setBackColor(COLOR_RED);
lcd.drawRect( 100,  100,  50, 30);
lcd.setBackColor(COLOR_GREEN);
lcd.drawRect( 200,  200,  50, 30);
comptAff=true;// on passe la variable d'affichage a vrai pour qu'au prochain cycle cette partie du code ne soit pas réécrite
break;
case 1:
// Ici on affichera no variable :
// Exemple l'heure
    lcd.setFont(small);
    lcd.setColor(COLOR_BLACK);
    lcd.setBackColor(COLOR_WHITE);
     sprintf(Buff_20,"heure:%2i:%02i:%2i",Time.h,Time.m,Time.s);
    lcd.print(Buff_20,30, 30);
// On test s'il y a appuis sur la zone situer au pixel 100,100 //de longueur 50pixel et de hauteur 30pixel
    if (TestTouche( 100, 100,50,30)== true ){
selecteurPage=1;// on sélectionne la nouvelle page a aficher
comptAff=false;// on oublie pas de réinitialiser notre variable d'affichage
      return;
    }
// on test s'il y a appuis sur la zone situer au pixel 200,200 //de longueur 50pixel et de hauteur 30pixel
    if (TestTouche( 200, 200,50,30)== true ){
selecteurPage=2;// on sélectionne la nouvelle page a afficher
comptAff=false;
      return;
    }
break;
}
  return;
}


Dans le déroulement de notre code on va au premier passage afficher, tout ce qui est statique et ignorer ce qui est dynamique. Au second et tous les autres passages on ignorera la partie statique et on affichera que la partie dynamique, jusqu'au moment ou une action sur une touche de changement de page réinitialise la variable « comptAff ».


Conclusion :

Voila, regardez bien le déroulement du code et vous comprendrez en lisant les commentaires. Les variable et exemple sont des « EXEMPLE » le code n'est pas tester à vous de coder en fonction de votre besoin.
enfin certain vont ce demander pourquoi cette histoire de multiple de 10 pour les menus et bien c'est simple vous voulez créer un bouton retour, vous n'avez alors qu'a diviser par 10 la variable « sélecteur de page » et hop vous retournez en arrière d'un niveau!  
Code: [Select]
selecteurPage=selecteurPage/10;
 


Version .doc : Tutoriel_ menu_tactile.doc



Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy