702 lines
21 KiB
C
702 lines
21 KiB
C
#include "controleur.h"
|
|
|
|
|
|
ErrEnum controlePoints(sfRenderWindow *window, const char *cheminFichier, Mode mode)
|
|
{
|
|
// Ceci est le flag qui sera mis à jour, puis renvoyé à la fin de la fonction
|
|
ErrEnum flag;
|
|
|
|
// La texture de rendus qui va servir tout le long...
|
|
sfRenderTexture *const renderTexture = initialisationRenderTexture(sfRenderWindow_getSize(window).x, sfRenderWindow_getSize(window).y);
|
|
|
|
// Voilà le sprite qui sera utilisé également
|
|
sfSprite *renderSprite = NULL;
|
|
|
|
// Maintenant les variables d'affichage créées, on peut dessiner à l'écran notre écran de chargement...
|
|
afficherLoading(window, renderTexture, &renderSprite);
|
|
|
|
// La fonte qui servira pour l'affichage des dates...
|
|
sfFont *const font = loadFontFromFile(BOLDFONTPATH);
|
|
|
|
// Quelques variables pour les routes et les agglomérats
|
|
uint32_t nbElements = 0, nbPointsAffiches = 0, nbAgglosAffiches = 0;
|
|
uint32_t nbAgglos = 0, nbPointAgglosMin = 0;
|
|
uint32_t nbRoutes = 0, nbAggloGlobaux = 0;
|
|
|
|
// Les futurs tableaux qui contiendront les points / agglomérats / routes / agglomérats globaux
|
|
Point *tabPoints = NULL;
|
|
Agglomerat *agglos = NULL;
|
|
Route *routes = NULL;
|
|
AgglomeratGlobal *aggloGlobaux = NULL;
|
|
|
|
/* Ci-dessous:
|
|
* La variable d'évènements maîtresse ;
|
|
* La structure `Rectangle` retournée par la fonction d'attente d'évènements ;
|
|
* La variable qui sert de flag entre le Contrôleur et la fonction d'attente d'évènements ;
|
|
* Un booléen pour indiquer quand il faut centrer le curseur sur l'écran ;
|
|
* Un booléen qui indique si on affiche tous les points, même ceux de type Agglo ;
|
|
* Un booléen qui indique s'il faudra vider la pile des vues suivantes.
|
|
*/
|
|
sfEvent event;
|
|
Rectangle carre;
|
|
Action action = NO_ACTION;
|
|
Tool currentTool = NO_TOOL;
|
|
bool centerCursor = false;
|
|
bool allPoint = false;
|
|
bool allRoads = true;
|
|
bool viderPileSuivante;
|
|
|
|
// Un pointeur sur une carte qui stockera successivement les vues.
|
|
Carte *carte = creerCarte(NULL);
|
|
|
|
// Nos deux piles qui vont gérer les vues successives de l'utilisateur !
|
|
PileCartes previous, next;
|
|
initialiserPileCartes(&previous);
|
|
initialiserPileCartes(&next);
|
|
|
|
/* HERE START THE OPERATIONS */
|
|
|
|
// On vient lire les logs de géolocalisation
|
|
flag = loadLogs(cheminFichier, &tabPoints, &nbElements);
|
|
if(flag != LOAD_SUCCESS)
|
|
{
|
|
if(flag == CORRUPTED_FILE)
|
|
{
|
|
warningBox(window, renderSprite, "Impossible d\'ouvrir ce fichier, est-il au bon format ?\n\nFormat attendu:\t\'date:tttttttttt,lat:xx.xxxxxx,long:yy.yyyyyy;\'");
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
//On initilise toutes les structures et met à jour les types et les pointeurs des points.
|
|
flag = initStructures(tabPoints, nbElements, &agglos, &nbAgglos, &routes, &nbRoutes, &aggloGlobaux, &nbAggloGlobaux);
|
|
if(flag != SUCCESS)
|
|
{
|
|
return flag;
|
|
}
|
|
|
|
// Deux petits tableaux pour sauvegarder l'adresse des points et agglomérats affichés en mémoire
|
|
sfCircleShape** tabPointeursCercles = calloc(nbElements, sizeof(sfCircleShape*));
|
|
sfCircleShape** tabPointeursCerclesAgglos = calloc(nbAgglos, sizeof(sfCircleShape*));
|
|
|
|
sfVertexArray **tabPointeursArray = calloc(nbRoutes, sizeof(sfVertexArray*));
|
|
|
|
// On lance la procédure de conversion des dates
|
|
char **tabDatesConverties = conversionDates(tabPoints, nbElements);
|
|
if(tabDatesConverties == NULL)
|
|
{
|
|
free(tabPoints);
|
|
free(agglos);
|
|
free(routes);
|
|
free(aggloGlobaux);
|
|
free(tabPointeursCercles);
|
|
free(tabPointeursCerclesAgglos);
|
|
free(tabPointeursArray);
|
|
sfFont_destroy(font);
|
|
detruirePileCartes(&next);
|
|
detruirePileCartes(&previous);
|
|
return ALLOCATION_FAILURE;
|
|
}
|
|
|
|
// Lors de la première itération, on récupère les positions extrêmes des points
|
|
getExtrema(tabPoints, nbElements, &carte->pointHautGauche, &carte->pointBasDroite);
|
|
// ... puis le point central le plus adapté
|
|
calculPointCentral(carte);
|
|
// ... et enfin on calcule le zoom et l'échelle ad hoc
|
|
getZoomEchelle(carte);
|
|
|
|
bool keepGoing = true;
|
|
do
|
|
{
|
|
// Il est temps de récupérer la-dite carte !
|
|
if(!getBackgroundMap(carte))
|
|
{
|
|
warningBox(window, renderSprite, "Une erreur est survenue durant le téléchargement de la carte. Êtes-vous connecté à Internet ?");
|
|
flag = REQUEST_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// On convertit les points en coordonnées cartésiennes !
|
|
conversionPoints(tabPoints, nbElements, &carte->pointCentral, carte->echelle);
|
|
|
|
// On convertit les agglos en coordonnées cartésiennes !
|
|
conversionAgglos(agglos, nbAgglos, &carte->pointCentral, carte->echelle);
|
|
|
|
// On affiche la carte !
|
|
afficherCarte(renderTexture, &carte->mapTexture, &carte->mapSprite, MAPFILE);
|
|
|
|
// Sert à indiquer si l'utilisateur pourra zoomer ou non (au clic) sur la carte
|
|
action = (carte->zoom < ZOOMAX ? ACTION_ZOOMABLE : ACTION_UNZOOMABLE);
|
|
|
|
if(mode == MODE_GLOBAL || mode == MODE_PREVIEW || mode == MODE_PREVIEW_SUGG || mode == MODE_PBP_AUTOMATIC || mode == MODE_PBP_MANUAL)
|
|
{
|
|
nbPointAgglosMin = getMinAgglo(agglos, nbAgglos);
|
|
|
|
// Gestion du menu
|
|
Menu menu;
|
|
initialiserMenu(&menu);
|
|
|
|
if(mode == MODE_PBP_AUTOMATIC || mode == MODE_PBP_MANUAL)
|
|
{
|
|
updateAndDrawMenu(renderTexture, &menu, mode, false, true, currentTool);
|
|
}
|
|
|
|
Point **ptsAffiches = affichageLogs(window, renderTexture, tabPoints, nbElements, &nbPointsAffiches, nbPointAgglosMin, tabPointeursCercles, agglos, nbAgglos, routes, nbRoutes, tabPointeursArray, tabPointeursCerclesAgglos, &nbAgglosAffiches, allPoint, allRoads, carte, mode, &menu);
|
|
if(ptsAffiches == NULL)
|
|
{
|
|
free(tabPoints);
|
|
free(agglos);
|
|
free(routes);
|
|
free(aggloGlobaux);
|
|
free(tabPointeursCercles);
|
|
free(tabPointeursCerclesAgglos);
|
|
free(tabPointeursArray);
|
|
freeTabGeneric((void***)&tabDatesConverties, nbElements);
|
|
sfFont_destroy(font);
|
|
detruirePileCartes(&next);
|
|
detruirePileCartes(&previous);
|
|
if(nbPointsAffiches == 0 && nbAgglosAffiches == 0)
|
|
{
|
|
return SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
return ALLOCATION_FAILURE;
|
|
}
|
|
}
|
|
|
|
// On tente un truc: Si l'affichage des logs est terminé, on passe en mode global :O
|
|
if(mode == MODE_PBP_AUTOMATIC || mode == MODE_PBP_MANUAL)
|
|
{
|
|
mode = MODE_GLOBAL;
|
|
afficherSablier(window, renderTexture, &renderSprite);
|
|
libererMemoireElementsAffiches(carte, nbPointsAffiches, tabPointeursCercles, nbAgglosAffiches, tabPointeursCerclesAgglos, nbRoutes, tabPointeursArray);
|
|
detruireMenu(&menu);
|
|
renderSprite = NULL;
|
|
free(ptsAffiches);
|
|
ptsAffiches = NULL;
|
|
continue;
|
|
}
|
|
|
|
// Si l'utilisateur a (dé)zoomé, on re-centre son curseur au milieu de l'écran juste avant de lui rendre la main !
|
|
if(centerCursor)
|
|
{
|
|
sfMouse_setPosition((sfVector2i){WIDTH / 2, HEIGHT / 2}, (sfWindow*)window);
|
|
centerCursor = false;
|
|
}
|
|
|
|
updateAndDrawMenu(renderTexture, &menu, mode, true, true, currentTool);
|
|
|
|
freeSprite(&renderSprite);
|
|
renderSprite = loadSpriteFromRenderTexture(renderTexture);
|
|
displayBackgroundSprite(window, renderSprite);
|
|
|
|
carre = waitingOnMapEvent(window, &event, renderTexture, renderSprite, carte, nbPointsAffiches, ptsAffiches, tabPointeursCercles, nbAgglos, tabPointeursCerclesAgglos, agglos, nbElements, tabPoints, tabDatesConverties, font, &action, mode, &menu, ¤tTool);
|
|
|
|
detruireMenu(&menu);
|
|
|
|
// Nous pouvons remettre ce sprite à `NULL` car il a été (normalement) correctement libéré dans la fonction d'attente ci-dessus !
|
|
renderSprite = NULL;
|
|
free(ptsAffiches);
|
|
ptsAffiches = NULL;
|
|
}
|
|
|
|
else
|
|
{
|
|
warningBox(window, renderSprite, "Le mode renseigné par le DÉVELOPPEUR n\'est pas correct :P.\n");
|
|
flag = MODE_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Action par défaut...
|
|
viderPileSuivante = false;
|
|
|
|
switch(action)
|
|
{
|
|
case ACTION_QUIT:
|
|
// L'utilisateur a décidé de quitter cette vue de la carte !
|
|
flag = SUCCESS;
|
|
keepGoing = false;
|
|
break;
|
|
|
|
case ACTION_REFRESH:
|
|
break;
|
|
|
|
case ACTION_ZOOM_IN:
|
|
case ACTION_ZOOM_OUT:
|
|
case ACTION_ZOOM_ZONE:
|
|
viderPileSuivante = true;
|
|
|
|
afficherSablier(window, renderTexture, &renderSprite);
|
|
|
|
// On empile cette carte dans la pile des cartes précédentes
|
|
if(!empilerPileCartes(&previous, carte))
|
|
{
|
|
afficherWarningPile(window, renderSprite);
|
|
break;
|
|
}
|
|
|
|
// On crée une nouvelle carte pour la vue demandée (qui possèdera les mêmes champs que la carte actuelle [cf. la documentation de la fonction])
|
|
carte = creerCarte(carte);
|
|
|
|
if(action == ACTION_ZOOM_ZONE)
|
|
{
|
|
/* ZOOM ZONE (CLIC) */
|
|
|
|
// On convertit les pixels retournés en coordonnées géographiques...
|
|
conversionRec(&carre, &carte->pointHautGauche, &carte->pointBasDroite, &carte->pointCentral, carte->echelle);
|
|
|
|
// On calcule le zoom et l'échelle adaptés à la nouvelle zone
|
|
getZoomEchelle(carte);
|
|
|
|
// ainsi qu'un nouveau point central !
|
|
calculPointCentral(carte);
|
|
}
|
|
|
|
else
|
|
{
|
|
/* ZOOMS MOLETTE */
|
|
|
|
// En fonction du sens de rotation de la molette (renvoyé par `waitingOnMapEvent`, on agrandit ou diminue le zoom)
|
|
carte->zoom += (action == ACTION_ZOOM_IN ? 1 : -1);
|
|
|
|
// On convertit la position du curseur en coordonnées GPS, et on stocke les valeurs dans la structure représentant (le nouveau) point central de la carte
|
|
conversionPixelsCoordonnees(&carte->pointCentral, &(sfVector2f){(double)event.mouseWheel.x, (double)event.mouseWheel.y}, &carte->pointCentral, carte->echelle);
|
|
|
|
carte->echelle = getEchelleFromZoom(carte->zoom);
|
|
|
|
// Pour ne pas dérouter l'utilisateur pendant son (dé)zoom, on centrera son cuseur au milieu de la carte !
|
|
centerCursor = true;
|
|
}
|
|
break;
|
|
|
|
case ACTION_ZOOM_NEXT:
|
|
case ACTION_ZOOM_PREV:
|
|
// L'utilisateur a demandé d'afficher la vue précédente / suivante. Donc on commence par empiler la vue actuelle dans la pile des suivantes / précédentes.
|
|
if(!empilerPileCartes((action == ACTION_ZOOM_NEXT ? &previous : &next), carte))
|
|
{
|
|
afficherWarningPile(window, renderSprite);
|
|
break;
|
|
}
|
|
|
|
// La prochaine vue correspond donc à la dernière empilée dans les suivantes / précédentes
|
|
carte = depilerPilesCartes((action == ACTION_ZOOM_NEXT ? &next : &previous));
|
|
|
|
// Gestion de la pile vide: On remet la vue que l'on a précédemment empilée (avantage: aucune variable temporaire)
|
|
if(carte == NULL)
|
|
{
|
|
carte = depilerPilesCartes((action == ACTION_ZOOM_NEXT ? &previous : &next));
|
|
}
|
|
|
|
else
|
|
{
|
|
// ... la pile n'est pas vide = il va y avoir un changement de carte = on affiche le sablier pendant le chargement !
|
|
afficherSablier(window, renderTexture, &renderSprite);
|
|
}
|
|
break;
|
|
|
|
case ACTION_CHANGE_MAP_TYPE:
|
|
afficherSablier(window, renderTexture, &renderSprite);
|
|
if(++carte->type == LASTYPE)
|
|
{
|
|
carte->type = FIRSTYPE + 1;
|
|
}
|
|
break;
|
|
|
|
case ACTION_CHANGE_VISUALISATION:
|
|
if(mode == MODE_GLOBAL)
|
|
{
|
|
mode = MODE_PREVIEW;
|
|
}
|
|
else if(mode == MODE_PREVIEW)
|
|
{
|
|
mode = MODE_PREVIEW_SUGG;
|
|
}
|
|
else if(mode == MODE_PREVIEW_SUGG)
|
|
{
|
|
mode = MODE_GLOBAL;
|
|
}
|
|
break;
|
|
|
|
case ACTION_CENTERPOSITION:
|
|
viderPileSuivante = true;
|
|
|
|
afficherSablier(window, renderTexture, &renderSprite);
|
|
|
|
if(!empilerPileCartes(&previous, carte))
|
|
{
|
|
afficherWarningPile(window, renderSprite);
|
|
break;
|
|
}
|
|
|
|
carte = creerCarte(NULL);
|
|
|
|
getExtrema(tabPoints, nbElements, &carte->pointHautGauche, &carte->pointBasDroite);
|
|
calculPointCentral(carte);
|
|
getZoomEchelle(carte);
|
|
break;
|
|
|
|
case ACTION_REPEAT:
|
|
break;
|
|
|
|
case ACTION_TOGGLEAGGLO:
|
|
afficherSablier(window, renderTexture, &renderSprite);
|
|
allPoint = !allPoint;
|
|
break;
|
|
|
|
case ACTION_TOGGLEROUTE:
|
|
afficherSablier(window, renderTexture, &renderSprite);
|
|
allRoads = !allRoads;
|
|
break;
|
|
|
|
default:
|
|
errorBox(window, "Erreur fatale.\n");
|
|
}
|
|
|
|
if(viderPileSuivante)
|
|
{
|
|
detruirePileCartes(&next);
|
|
initialiserPileCartes(&next);
|
|
}
|
|
|
|
libererMemoireElementsAffiches(carte, nbPointsAffiches, tabPointeursCercles, nbAgglosAffiches, tabPointeursCerclesAgglos, nbRoutes, tabPointeursArray);
|
|
|
|
} while(keepGoing); // Ceci est bien entendu une fausse boucle infinie (cf. le test juste ci-dessus...)
|
|
|
|
detruirePileCartes(&next);
|
|
detruirePileCartes(&previous);
|
|
sfFont_destroy(font);
|
|
free(tabPoints);
|
|
free(agglos);
|
|
free(routes);
|
|
free(aggloGlobaux);
|
|
freeTabGeneric((void***)&tabDatesConverties, nbElements);
|
|
free(tabPointeursCercles);
|
|
free(tabPointeursCerclesAgglos);
|
|
free(tabPointeursArray);
|
|
|
|
return flag;
|
|
}
|
|
|
|
|
|
ErrEnum controleMultipleLogs(sfRenderWindow *const window, char selectedFiles[MAXSELECTEDFILES][MAXPATHLENGTH], const uint16_t nbFiles)
|
|
{
|
|
ErrEnum flag;
|
|
|
|
sfRenderTexture *const renderTexture = initialisationRenderTexture(sfRenderWindow_getSize(window).x, sfRenderWindow_getSize(window).y);
|
|
sfSprite *renderSprite = NULL;
|
|
|
|
sfFont *font = loadFontFromFile(BOLDFONTPATH);
|
|
|
|
afficherLoading(window, renderTexture, &renderSprite);
|
|
|
|
uint32_t sommeNbElements = 0;
|
|
|
|
Point *tabTabPoints[nbFiles];
|
|
uint32_t tabNbPoints[nbFiles];
|
|
|
|
Agglomerat *tabAgglos[nbFiles];
|
|
uint32_t tabNbAgglos[nbFiles];
|
|
|
|
Agglomerat *tabAggloTotal = NULL;
|
|
uint32_t tailleTabAggloTotal = 0;
|
|
|
|
AgglomeratGlobal *globalMultiFile = NULL;
|
|
uint32_t tailleGlobalMultiFile = 0;
|
|
|
|
// Pour chaque fichier de logs, on vient charger les éléments en mémoire un à un...
|
|
for(uint16_t i = 0; i < nbFiles; i++)
|
|
{
|
|
flag = loadLogs(selectedFiles[i], &tabTabPoints[i], &tabNbPoints[i]);
|
|
if(flag != LOAD_SUCCESS)
|
|
{
|
|
for(int16_t j = i - 1; j >= 0; j--)
|
|
{
|
|
free(tabTabPoints[j]);
|
|
}
|
|
|
|
return flag;
|
|
}
|
|
|
|
sommeNbElements += tabNbPoints[i];
|
|
|
|
flag = repereAgglo(tabTabPoints[i], tabNbPoints[i], &tabAgglos[i], &tabNbAgglos[i]);
|
|
if(flag != SUCCESS)
|
|
{
|
|
for(int16_t j = i; j >= 0; j--)
|
|
free(tabTabPoints[j]);
|
|
|
|
for(int16_t j = i - 1; j >= 0; j--)
|
|
free(tabAgglos[i]);
|
|
|
|
return flag;
|
|
}
|
|
}
|
|
|
|
/* Chaque fichier de log est chargé => réunion des tableaux d'agglos en un seul */
|
|
|
|
// On compte combien il y a d'agglos
|
|
for(uint32_t i = 0; i < nbFiles; ++i)
|
|
tailleTabAggloTotal += tabNbAgglos[i];
|
|
|
|
// Le calloc des familles pas très propre
|
|
tabAggloTotal = calloc(tailleTabAggloTotal, sizeof(*tabAggloTotal));
|
|
if(tabAggloTotal == NULL)
|
|
{
|
|
fprintf(stderr, "%s\n", strerror(errno));
|
|
|
|
for(uint16_t i = 0; i < nbFiles; i++)
|
|
free(tabTabPoints[i]);
|
|
|
|
for(uint16_t i = 0; i < nbFiles; i++)
|
|
free(tabAgglos[i]);
|
|
|
|
return ALLOCATION_FAILURE;
|
|
}
|
|
|
|
for(uint32_t i = 0, k = 0; i < nbFiles; ++i)
|
|
{
|
|
for(uint32_t j = 0; j < tabNbAgglos[i]; ++j, ++k)
|
|
{
|
|
tabAggloTotal[k] = tabAgglos[i][j];
|
|
}
|
|
|
|
free(tabAgglos[i]); // <-- À surveiller
|
|
}
|
|
|
|
flag = assemblageGlobalAgglo(tabAggloTotal, tailleTabAggloTotal, &globalMultiFile, &tailleGlobalMultiFile);
|
|
if(flag != SUCCESS)
|
|
{
|
|
free(tabAggloTotal);
|
|
|
|
for(uint16_t i = 0; i < nbFiles; i++)
|
|
free(tabTabPoints[i]);
|
|
|
|
return flag;
|
|
}
|
|
|
|
// Une variable de type carte pour stocker quelques infos sur notre vue actuelle...
|
|
Carte *carte = creerCarte(NULL);
|
|
|
|
// Un tableau pour sauvegarder l'adresse des cercles dessinés à l'écran
|
|
sfCircleShape** tabPointeursCerclesAgglos = calloc(tailleGlobalMultiFile, sizeof(sfCircleShape*));
|
|
uint32_t nbPointAgglosAffiches = 0;
|
|
|
|
Point *positionAgglos = calloc(tailleGlobalMultiFile, sizeof(*positionAgglos));
|
|
if(positionAgglos == NULL)
|
|
{
|
|
free(globalMultiFile);
|
|
|
|
free(tabAggloTotal);
|
|
|
|
for(uint16_t i = 0; i < nbFiles; i++)
|
|
free(tabTabPoints[i]);
|
|
|
|
return ALLOCATION_FAILURE;
|
|
}
|
|
|
|
// On copie les coordonnées de ces agglomérats dans un tableau de Points (pour utiliser les fonctions déjà implémentées)
|
|
for(uint16_t i = 0; i < tailleGlobalMultiFile; i++)
|
|
{
|
|
positionAgglos[i].pos = globalMultiFile[i].moy;
|
|
|
|
// On profite de cette itération pour charger en mémoire les adresses des agglomérats
|
|
// Elle tient sur une seule ligne, mais c'est une opération très importante.
|
|
char *temp = getReverseGeocoding(&globalMultiFile[i].moy);
|
|
globalMultiFile[i].adresse = (temp != NULL ? getRidOfAccents(temp) : NULL);
|
|
}
|
|
|
|
getExtrema(positionAgglos, tailleGlobalMultiFile, &carte->pointHautGauche, &carte->pointBasDroite);
|
|
calculPointCentral(carte);
|
|
getZoomEchelle(carte);
|
|
|
|
/* Variables de contrôleur */
|
|
Menu menu;
|
|
initialiserMenu(&menu);
|
|
|
|
PileCartes previous, next;
|
|
initialiserPileCartes(&previous);
|
|
initialiserPileCartes(&next);
|
|
|
|
sfEvent event;
|
|
bool viderPileSuivante;
|
|
bool centerCursor = false;
|
|
Action action = NO_ACTION;
|
|
Tool currentTool = NO_TOOL;
|
|
|
|
bool keepGoing = true;
|
|
do
|
|
{
|
|
if(!getBackgroundMap(carte))
|
|
{
|
|
warningBox(window, renderSprite, "Une erreur est survenue durant le téléchargement de la carte. Êtes-vous connecté à Internet ?");
|
|
flag = REQUEST_FAILURE;
|
|
break;
|
|
}
|
|
|
|
conversionPoints(positionAgglos, tailleGlobalMultiFile, &carte->pointCentral, carte->echelle);
|
|
|
|
// Une fois les conversions faites, on repasse dans l'autre sens !
|
|
for(uint16_t i = 0; i < tailleGlobalMultiFile; i++)
|
|
{
|
|
globalMultiFile[i].moyConv = positionAgglos[i].posConv;
|
|
}
|
|
|
|
afficherCarte(renderTexture, &carte->mapTexture, &carte->mapSprite, MAPFILE);
|
|
|
|
const uint32_t nbPointAgglosMin = getMinAggloGlobal(globalMultiFile, tailleGlobalMultiFile);
|
|
|
|
for(uint16_t i = 0; i < tailleGlobalMultiFile; i++)
|
|
{
|
|
if(pointOnMap(&globalMultiFile[i].moyConv))
|
|
{
|
|
dessinerAggloGlobal(renderTexture, &globalMultiFile[i], &tabPointeursCerclesAgglos[i], nbPointAgglosMin, carte, COULEUR_AGGLO);
|
|
nbPointAgglosAffiches++;
|
|
}
|
|
}
|
|
|
|
updateAndDrawMenu(renderTexture, &menu, MODE_MULTI_FILES, false, false, currentTool);
|
|
|
|
if(centerCursor)
|
|
{
|
|
sfMouse_setPosition((sfVector2i){WIDTH / 2, HEIGHT / 2}, (sfWindow*)window);
|
|
centerCursor = false;
|
|
}
|
|
|
|
freeSprite(&renderSprite);
|
|
renderSprite = loadSpriteFromRenderTexture(renderTexture);
|
|
displayBackgroundSprite(window, renderSprite);
|
|
|
|
action = (carte->zoom < ZOOMAX ? ACTION_ZOOMABLE : ACTION_UNZOOMABLE);
|
|
|
|
Rectangle carre = waitingOnMapEventAgglo(window, &event, renderTexture, renderSprite, carte, tailleGlobalMultiFile, globalMultiFile, tabPointeursCerclesAgglos, font, &action, &menu, ¤tTool);
|
|
renderSprite = NULL;
|
|
|
|
viderPileSuivante = false;
|
|
|
|
switch(action)
|
|
{
|
|
case ACTION_QUIT:
|
|
flag = SUCCESS;
|
|
keepGoing = false;
|
|
break;
|
|
|
|
case ACTION_ZOOM_IN:
|
|
case ACTION_ZOOM_OUT:
|
|
case ACTION_ZOOM_ZONE:
|
|
viderPileSuivante = true;
|
|
afficherSablier(window, renderTexture, &renderSprite);
|
|
if(!empilerPileCartes(&previous, carte))
|
|
{
|
|
afficherWarningPile(window, renderSprite);
|
|
break;
|
|
}
|
|
|
|
carte = creerCarte(carte);
|
|
|
|
if(action == ACTION_ZOOM_ZONE)
|
|
{
|
|
conversionRec(&carre, &carte->pointHautGauche, &carte->pointBasDroite, &carte->pointCentral, carte->echelle);
|
|
getZoomEchelle(carte);
|
|
calculPointCentral(carte);
|
|
}
|
|
|
|
else
|
|
{
|
|
carte->zoom += (action == ACTION_ZOOM_IN ? 1 : -1);
|
|
conversionPixelsCoordonnees(&carte->pointCentral, &(sfVector2f){(double)event.mouseWheel.x, (double)event.mouseWheel.y}, &carte->pointCentral, carte->echelle);
|
|
carte->echelle = getEchelleFromZoom(carte->zoom);
|
|
centerCursor = true;
|
|
}
|
|
break;
|
|
|
|
case ACTION_ZOOM_NEXT:
|
|
case ACTION_ZOOM_PREV:
|
|
if(!empilerPileCartes((action == ACTION_ZOOM_NEXT ? &previous : &next), carte))
|
|
{
|
|
afficherWarningPile(window, renderSprite);
|
|
break;
|
|
}
|
|
carte = depilerPilesCartes((action == ACTION_ZOOM_NEXT ? &next : &previous));
|
|
if(carte == NULL)
|
|
{
|
|
carte = depilerPilesCartes((action == ACTION_ZOOM_NEXT ? &previous : &next));
|
|
}
|
|
else
|
|
{
|
|
afficherSablier(window, renderTexture, &renderSprite);
|
|
}
|
|
break;
|
|
|
|
case ACTION_CHANGE_MAP_TYPE:
|
|
afficherSablier(window, renderTexture, &renderSprite);
|
|
if(++carte->type == LASTYPE)
|
|
{
|
|
carte->type = FIRSTYPE + 1;
|
|
}
|
|
break;
|
|
|
|
case ACTION_CENTERPOSITION:
|
|
viderPileSuivante = true;
|
|
|
|
afficherSablier(window, renderTexture, &renderSprite);
|
|
|
|
if(!empilerPileCartes(&previous, carte))
|
|
{
|
|
afficherWarningPile(window, renderSprite);
|
|
break;
|
|
}
|
|
|
|
carte = creerCarte(NULL);
|
|
|
|
getExtrema(positionAgglos, tailleGlobalMultiFile, &carte->pointHautGauche, &carte->pointBasDroite);
|
|
calculPointCentral(carte);
|
|
getZoomEchelle(carte);
|
|
break;
|
|
|
|
case ACTION_REPEAT:
|
|
break;
|
|
|
|
default:
|
|
errorBox(window, "Erreur fatale.\n");
|
|
}
|
|
|
|
if(viderPileSuivante)
|
|
{
|
|
detruirePileCartes(&next);
|
|
initialiserPileCartes(&next);
|
|
}
|
|
|
|
libererMemoireElementsAffichesAgglos(carte, tailleGlobalMultiFile, tabPointeursCerclesAgglos);
|
|
nbPointAgglosAffiches = 0;
|
|
|
|
} while(keepGoing);
|
|
|
|
detruireMenu(&menu);
|
|
|
|
detruirePileCartes(&next);
|
|
initialiserPileCartes(&next);
|
|
|
|
sfFont_destroy(font);
|
|
|
|
freeSprite(&renderSprite);
|
|
sfRenderTexture_destroy(renderTexture);
|
|
|
|
for(uint16_t i = 0; i < tailleGlobalMultiFile; i++)
|
|
{
|
|
free(globalMultiFile[i].adresse);
|
|
}
|
|
|
|
free(globalMultiFile);
|
|
|
|
free(tabAggloTotal);
|
|
|
|
for(uint16_t i = 0; i < nbFiles; i++)
|
|
free(tabTabPoints[i]);
|
|
|
|
free(positionAgglos);
|
|
|
|
free(tabPointeursCerclesAgglos);
|
|
|
|
return flag;
|
|
}
|