Bonjour à tous,
j'utilise un afficheur et pour ce dernier j'ai plein de fonctions utiles pour me permettre d'afficher une liste déroulante, une liste à choix simples, choix multiples etc... Mon objectif est de réussir à simplifier ces fonctions, simplifier dans le sens : 'un code plus simple à relire et sur moins de ligne'.
J'ai réalisé pas mal de modification mais j'ai l'intime conviction que mes fonctions utilisent des principes qui pourrait être réécrit sur beaucoup moins de ligne, comme par exemple ici:
où je met tout dans un buffer un par un, je trouve ça pas très propre et je suis quasi sur qu'il y a un autre moyen de le faire plus simplement mais je ne sais comment :/ !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 if (currentSelect > 1) //si lelement nest pas le premier de la liste { buffer[0] = '['; if (state[currentSelect - 2]) //on verifie letat de lelement du dessus, currentSelect est incrementé donc // -2 signifie que l'on regarde l'etat de l'element de la liste avant lelement courant buffer[1] = '*'; else buffer[1] = ' '; buffer[2] = ']'; buffer[3] = ' '; strncpy((char *) &buffer[4], (char *) label[currentSelect - 2], COLUMN_N - 4);
Voilà j'espère avoir été assez clair sur mes besoins ! Si vous avez des astuces de simplification pour mon code ci-dessous je suis preneur.
Merci beaucoup d'avance pour votre temps et votre générosité ! A bientôt je l’espère !
(Ci-dessous le code en brut où j'ai au maximum essayé de commenter, mais bien sur vous n'êtes pas obliger de tous regarder)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 /** * @brief Display visible elements of a scrolling list * * @param[in] label Array with strings for all possible choices of the scrolling list * @param[in] nbElem Number of possible choices * @param[in] currentSelect The current selected index in the list */ void displayScrollingListVisibleElements(const unsigned char * const label[], unsigned char nbElem, unsigned char currentSelect) { unsigned char buffer[COLUMN_N + 1]; unsigned char length; if (currentSelect > 0) //si l'index de la liste est supérieur à 0 { //cest que l'on nest pas au debut donc on affiche a la ligne 2 //lelement precedent car notre selection courante est a la ligne 3 displayOled(2, label[currentSelect - 1]); if (currentSelect > 1) //si notre ligne courante est superieur a 1 //cest que il ya des menus a afficher au dessus addSymbol(2, 19, SYMBOL_UPARROW);//on ajoute donc le symbole fleche du haut } else //sinon si index[0] c'est quon est au debut du menu donc on le montre avec la ligne 2 vide clearOledLine(2); buffer[0] = SYMBOL_RIGHTARROW; //on place la fleche vers la droite dans le buffer[0] strncpy((char *) &buffer[1], (char *) label[currentSelect], COLUMN_N - 3); //on copie le menu a partir de buffer[1] jusqua la colonne 17 length = (unsigned char) strlen((char *) buffer); //on place la longueur du buffer dans la var lenght buffer[length] = SYMBOL_LEFTARROW; //on ajoute une fleche vers la gauche au buffer equivalent a la longueur du menu plus la fleche vers la droite buffer[length + 1] = 0x00; //la colonne suivant vaut une case vide displayOled(3, buffer); //on affiche a la ligne 3 le buffer if (currentSelect < (nbElem - 1)) //si lelement courant est inferieur au nombre delem -1 { //autrement dit si il y a encore un element derriere lelement courant displayOled(4, label[currentSelect + 1]); //on affiche a la ligne 4, lelement courant +1 if (currentSelect < (nbElem - 2)) //si lelement courant est inferieur au nombre delem -2 //autrement dit sil il y a encore deux elements derriere lelement courant addSymbol(4, 19, SYMBOL_DOWNARROW); //on affiche fleche du bas } else //si il n'y a pas delement derriere lelement courant clearOledLine(4); //clear la ligne 4 }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 /** * @brief Display a menu scrolling list * * @param[in] title Title of the menu * @param[in] label Array with strings for all possible choices of the scrolling list * @param[in] nbElem Number of possible choices * @param[in] lastChoice The last selected element to display the correct page * * @return <tt>MENU_TIMEOUT</tt> if there is a menu timeout, <tt>MENU_ESCAPE</tt> if the user escape the menu * The number of currentSelect is return when the enter button is pressed */ unsigned char scrollingList(const unsigned char * const title, const unsigned char * const label[], unsigned char nbElem, unsigned char lastChoice) { unsigned char currentSelect = lastChoice; unsigned short timeOut = 0; unsigned char validChoice = FALSE; clearDisplay(); // Clears display displayCenterLine(1, title); //title on first line if (nbElem > 0) displayScrollingListVisibleElements(label, nbElem, currentSelect); waitAllButtonsRelases(); while (timeOut < MENU_TIMEOUTVALUE && !validChoice) { switch (getButtonPress()) { case BUTTON_UP: //previous element in list timeOut = 0; if (nbElem > 0 && currentSelect > 0) { currentSelect--; displayScrollingListVisibleElements(label, nbElem, currentSelect); } softDelay(MENU_TOUCHDELAY); break; case BUTTON_DOWN: //next element in list timeOut = 0; if (nbElem > 0 && currentSelect < nbElem - 1) { currentSelect++; displayScrollingListVisibleElements(label, nbElem, currentSelect); } softDelay(MENU_TOUCHDELAY); break; case BUTTON_ENTER: //valid current choice if (nbElem > 0) validChoice = TRUE; //currentSelect = MENU_VALID; //permet de revenir sur lelement courant quand on revient sur le menu break; case BUTTON_CLEAR: //escape menu validChoice = TRUE; currentSelect = MENU_ESCAPE; //permet de revenir sur lelement courant quand on revient sur le menu break; default: softDelay(20); timeOut++; break; } #ifdef WATCHDOG_IS_USED IWDG_ReloadCounter(); #endif } clearDisplay(); // Clears display if (timeOut == MENU_TIMEOUTVALUE) return MENU_TIMEOUT; else return currentSelect; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 /** * @brief Display visible elements of a single or multiple choice list * * @param[in] label Array with strings for all possible choices of the list * @param[in] state Array with state for all possible choices of the list (<tt>TRUE</tt> for checked, <tt>FALSE</tt> otherwise) * @param[in] nbElem Number of possible choices * @param[in] currentSelect The current selected index in the list (starting at 1, 0 and <tt>nbElem</tt>+1 correspond to valid/cancel option) */ void displaySingleOrMultipleChoiceListVisibleElements(const unsigned char * const label[], unsigned char state[], unsigned char nbElem, unsigned char currentSelect) { unsigned char buffer[COLUMN_N + 1]; unsigned char length; if (currentSelect > 1) //si lelement nest pas le premier de la liste { buffer[0] = '['; if (state[currentSelect - 2]) //on verifie letat de lelement du dessus, currentSelect est incrementé donc // -2 signifie que l'on regarde l'etat de l'element de la liste avant lelement courant buffer[1] = '*'; else buffer[1] = ' '; buffer[2] = ']'; buffer[3] = ' '; strncpy((char *) &buffer[4], (char *) label[currentSelect - 2], COLUMN_N - 4); displayOled(2, buffer); addSymbol(2, 19, SYMBOL_UPARROW); } else if (currentSelect == 1) //si on est sur le premier element de la liste (currentSelect à 1) displayOled(2, STR_VALID_CANCEL[0]); //on ajoute a la ligne 2 VALIDER/ANNULER else clearOledLine(2); //si lelement courant est valider/annuler (donc curentSelect à 0) on clear la ligne 2 buffer[0] = SYMBOL_RIGHTARROW; if (currentSelect == 0 || currentSelect == nbElem + 1) //si lelement courant est le premier ou le dernier : valider/annuler strncpy((char *) &buffer[1], (char *) STR_VALID_CANCEL[0], COLUMN_N - 3); else { buffer[1] = '['; if (state[currentSelect - 1]) //element courant incrementé donc -1 permet de vérif l'état de lelement courant buffer[2] = '*'; else buffer[2] = ' '; buffer[3] = ']'; buffer[4] = ' '; strncpy((char *) &buffer[5], (char *) label[currentSelect - 1], COLUMN_N - 7); } length = (unsigned char) strlen((char *) buffer); buffer[length] = SYMBOL_LEFTARROW; buffer[length + 1] = 0x00; displayOled(3, buffer); if (currentSelect < nbElem) //si lelement courant n'est pas le dernier de la liste { buffer[0] = '['; if (state[currentSelect]) buffer[1] = '*'; else buffer[1] = ' '; buffer[2] = ']'; buffer[3] = ' '; strncpy((char *) &buffer[4], (char *) label[currentSelect], COLUMN_N - 4); displayOled(4, buffer); addSymbol(4, 19, SYMBOL_DOWNARROW); } else if (currentSelect == nbElem) //si element courant est le dernier de la liste displayOled(4, STR_VALID_CANCEL[0]); //on affiche valider/quitter a la ligne 4 else clearOledLine(4); //valider/annuler en element courant donc clear la ligne 4 }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100 /** * @brief Display and process a multiple choices list * * @param[in] title Title of the menu * @param[in] label Array with strings for all possible choices of the list * @param[in] nbElem Number of possible choices (limited by <tt>MENU_MAXELEM</tt>) * @param[in,out] values For each element, TRUE to check, FALSE otherwise * * @return <tt>MENU_TIMEOUT</tt> if there is a menu timeout, <tt>MENU_ESCAPE</tt> if the user escape the menu * or <tt>MENU_VALID</tt> if an IP address was read */ unsigned char multipleChoicesList(const unsigned char * const title, const unsigned char * const label[], unsigned char nbElem,unsigned char *values) { unsigned char currentElement = 0; unsigned short timeOut = 0; unsigned char validChoice = FALSE; unsigned char returnValue = MENU_ESCAPE; unsigned char newValues[MENU_MAXELEM]; unsigned char index; for (index = 0; index < nbElem; ++index) newValues[index] = values[index]; clearDisplay(); //clear all screen displayCenterLine(1, title); //title on first line displaySingleOrMultipleChoiceListVisibleElements(label, newValues, nbElem, currentElement); waitAllButtonsRelases(); while (timeOut < MENU_TIMEOUTVALUE && !validChoice) { switch (getButtonPress()) { case BUTTON_UP: //previous element in list timeOut = 0; if (currentElement > 0) //si lelement courant nest pas valider/annuler { currentElement--; displaySingleOrMultipleChoiceListVisibleElements(label, newValues, nbElem, currentElement); } softDelay(MENU_TOUCHDELAY); break; case BUTTON_DOWN: //next element in list timeOut = 0; if (currentElement < nbElem + 1) //si lelement courant nest pas valider/annuler { currentElement++; displaySingleOrMultipleChoiceListVisibleElements(label, newValues, nbElem, currentElement); } softDelay(MENU_TOUCHDELAY); break; case BUTTON_ENTER: if (currentElement == 0 || currentElement == nbElem + 1) //si lelement courant est valider/annuler { validChoice = TRUE; // valid choice uint8_t count = 0; for (index = 0; index < nbElem; ++index) //on enregistre les valeurs true et false correspondant au cas { //coché du tableau newValues dans le tableau values values[index] = newValues[index]; if (values[index] == FALSE) count++; } if (nbElem == count) //si tous mes elements sont a faux (pas coché) returnValue = MENU_NOCHOICE; //on réaffiche le menu config else //sinon on a un ou des elements a vrai (coché) returnValue = MENU_VALID; //on affiche le menu suivant } else //si lelement courant est un champ du tableau { newValues[currentElement - 1] = TRUE; // add choice displaySingleOrMultipleChoiceListVisibleElements(label, newValues, nbElem, currentElement); } break; case BUTTON_CLEAR: if (currentElement == 0 || currentElement == nbElem + 1) { validChoice = TRUE; // escape manu returnValue = MENU_ESCAPE; } else { newValues[currentElement - 1] = FALSE; // remove choice displaySingleOrMultipleChoiceListVisibleElements(label, newValues, nbElem, currentElement); } break; default: softDelay(20); timeOut++; break; } #ifdef WATCHDOG_IS_USED IWDG_ReloadCounter(); #endif } clearDisplay(); //clear all screen if (timeOut == MENU_TIMEOUTVALUE) return MENU_TIMEOUT; else return returnValue; }
Partager