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:

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);
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 :/ !

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;
}