J'ai décidé de créer mon module de menus en partant de l'objet (réel) livre.
En effet, un livre est composé de pages qui, elles même contiennent des lignes que j'appellerai ici des Objets Visuels (qui sont des SDL_Surface*).
Le livre possède un pointeur de Page qui indique la page actuelle, c'est cette page qui est utilisée pour afficher les Objets Visuels lorsque l'on demande l'affichage.

Chaque Objet Visuel contient une surface et sa localisation (SDL_Rect) mais peut également contenir un lien (pointeur de Page) vers la page afin de créer des liaisons entre les rubriques du menu et la page correspondante à afficher.

Puisque j'ai tout construit à base de pointeur, je me demandai si mon implémentation était bonne (surtout au niveau des fuites mémoires).

Merci d'avance.



Les implémentations des classes décrites:
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
class ObjetVisuel;
class Page;
class Livre;
 
 
 
class ObjetVisuel
{
    public:
        ObjetVisuel(SDL_Surface* rendu, int x, int y);
        ~ObjetVisuel();
 
        SDL_Surface* GetSurface() { return surface; };
        SDL_Rect* GetRect() { return &position; };
 
        void SetLien(Page* page) { lien = page; };
        Page* GetLien() { return lien; };
 
    private:
        SDL_Surface* surface;
        SDL_Rect     position;
        Page*        lien;
};
 
ObjetVisuel::ObjetVisuel(SDL_Surface* rendu, int x, int y)
{
    surface = rendu;
    lien = NULL;
    position.x = x;
    position.y = y;
}
 
ObjetVisuel::~ObjetVisuel()
{
    if ( surface )
    {
        delete( surface );
    }
 
    lien = NULL;
    //cerr << "Destructeur d'Objet Visuel appelle.\n";
}
 
 
class Page
{
    public:
        Page(unsigned char nb_Objets);
        ~Page();
        void AjouterObjetVisuel(SDL_Surface* surface, int x, int y);
        ObjetVisuel* LireObjetVisuel(int indice);
        int LireNombreObjetsVisuels() { return (int)vElements.size(); };
        void Dessiner(SDL_Surface* ecran);
 
    private:
        vector<ObjetVisuel*> vElements;
};
 
Page::Page(unsigned char nb_Objets)
{
    if ( nb_Objets > 0 )
    {
        vElements.resize(nb_Objets);
 
        for(int i=0; i < nb_Objets; i++)
        {
            vElements[i] = NULL;
        }
    }
}
 
Page::~Page()
{
    // Desallocation des surfaces dans les objets visuels de chaque page.
    // Puis destruction de cette page.
    for(int i=0; i < (int)vElements.size(); i++)
    {
        if ( vElements[i] )
        {
            // On supprime l'objet visuel.
            delete( vElements[i] );
        }
    }
 
    //cerr << "Destructeur de Page appelle.\n";
}
 
void Page::AjouterObjetVisuel(SDL_Surface* surface, int x, int y)
{
    if ( surface ) // L'objet est valide ?
    {
        if ( vElements[vElements.size()-1] == NULL ) // Il y a de la place ?
        {
            ObjetVisuel* ov = new ObjetVisuel(surface, x, y);
            if ( ov )
            {
                vElements.push_back(ov);
            }
            else
            {
                cerr << "Allocation de ressource echouee pour l'objet visuel. (Page::AjouterObjetVisuel) \n";
            }
        }
        else
        {
            cerr << "La page est pleine (le vecteur d'objets visuels est plein). (Page::AjouterObjetVisuel) \n";
        }
    }
    else
    {
        cerr << "La surface passee en argument n'est pas valide. (Page::AjouterObjetVisuel) \n";
    }
}
 
void Page::Dessiner(SDL_Surface* ecran)
{
    for(int i=0; i < (int)vElements.size(); i++)
    {
        if ( vElements[i] )
        {
            SDL_BlitSurface(vElements[i]->GetSurface(), 0, ecran, vElements[i]->GetRect());
        }
    }
}
 
 
 
class Livre
{
    public:
        Livre(SDL_Surface* mainScreen);
        ~Livre();
 
        void AfficherPageCourante();
 
    private:
        list<Page*> lBouquin;
        SDL_Surface* moniteur;
        Page* pagecourante;
};
 
// On construit un livre standard.
Livre::Livre(SDL_Surface* mainScreen)
{
    pagecourante = NULL;
    Page* page = NULL;
    SDL_Surface* pictureLoader = NULL;
 
    page = new Page(1);
    pagecourante = page;
 
 
    pictureLoader = IMG_Load("Graphisme/Textures/logo.png");
    if ( pictureLoader )
    {
        page->AjouterObjetVisuel(pictureLoader, 282, 75);
    }
 
    lBouquin.push_front(page);
 
    moniteur = mainScreen;
}
 
Livre::~Livre()
{
    //list<Page*>::iterator pIterator;
    //vector<Page*> pagesToErase;
 
 
    while( lBouquin.size() > 0 )
    {
        cerr << "Taille de lBouquin: " << lBouquin.size() << endl;
        if ( lBouquin.front() )
        {
            delete ( lBouquin.front() );
        }
        lBouquin.pop_front();
    }
 
    pagecourante = NULL;
 
    cout << "Destructeur de Livre appelle.\n";
}
 
 
void Livre::AfficherPageCourante()
{
    pagecourante->Dessiner(moniteur);
}


Le bout de code qui crée le livre et l'exploite.
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
int GameEngine::RunTestBook()
{
    bool done = false;
 
    Livre* book = new Livre(mainFrame);
 
    while (!done)
    {
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            // check for messages
            switch (event.type)
            {
                case SDL_QUIT: done = true; break;
 
                case SDL_KEYDOWN:
                {
                    // exit if ESCAPE is pressed
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                    {
                        done = true;
                        break;
                    }
                }
            }
            SDL_FillRect(mainFrame, 0, SDL_MapRGB(mainFrame->format, 255, 255, 255));
            book->AfficherPageCourante();
            SDL_Flip(mainFrame);
        }
    }
 
    cerr << "delete book\n";
    delete (book);
 
    cerr << "\n\n\n";
    return 0;
}
Je précise que mainFrame est le SDL_Surface* qui représente l'écran.