class Scoreboard { String dataSource; // nom du fichier csv Table table; boolean autoload = true; // chargement et rechargement automatique boolean display = true; float posX, posY, width, height; // position et dimensions de l'afficheur Scoreboard() { this.dataSource = "scoreboard.csv"; this.setup(); } Scoreboard(String dataSource) { this.dataSource = dataSource; this.setup(); } void setup() { if (autoload) this.load(); this.posX = 1548; this.posY = 0; this.width = 300; this.height = 118; } // charge ou génère le tableau des scores void load() { if (fileExists(this.dataSource)) { this.table = loadTable("data/"+this.dataSource, "header"); } else { this.table = new Table(); this.table.addColumn("equipe"); this.table.addColumn("score"); this.table.addColumn("tour"); for (int i = 0 ; i < nombreEquipes; i++) { TableRow scoreEquipe = this.table.addRow(); scoreEquipe.setInt("equipe", i+1); scoreEquipe.setInt("score", 0); scoreEquipe.setInt("tour", 0); } } // typage forcé pour que .sort() fonctionne sur la colonne score this.table.setColumnType("score", "int"); this.table.setColumnType("tour", "int"); this.dataIntegrityCheck(); } // écrit le tableau des scores dans un .csv void save() { this.table = new Table(); this.table.addColumn("equipe"); this.table.addColumn("score"); this.table.addColumn("tour"); for (int i = 0 ; i < equipes.length; i++) { Equipe e = equipes[i]; TableRow scoreEquipe = this.table.addRow(); scoreEquipe.setInt("equipe", e.id+1); scoreEquipe.setInt("score", e.score); scoreEquipe.setInt("tour", e.tour); } saveTable(this.table, "data/"+this.dataSource, "csv"); } void reloadFromDisk() { //println("reload from disk"); this.load(); this.applyScores(); } int getScore(int i) { return this.table.getInt(i, "score"); } int getTour(int i) { return this.table.getInt(i, "tour"); } void applyScores() { for (TableRow row : this.table.rows()) { equipes[row.getInt("equipe")-1].setScore(row.getInt("score")); equipes[row.getInt("equipe")-1].setTour(row.getInt("tour")); } } void applyScore(int equipe, int score, int tour) { this.table.findRow(str(equipe+1), "equipe").setInt("score", score); this.table.findRow(str(equipe+1), "equipe").setInt("tour", tour); } Iterable findRows(String value, String name) { return this.table.findRows(value, name); } Iterable findEquipesByScore(int value) { return this.table.findRows(str(value), "score"); } boolean mouseHover() { if (mouseX > this.posX && mouseX < this.posX + this.width && mouseY > this.posY && mouseY < this.posY + height) return true; return false; } void toggleDisplay() { this.display = !this.display; } // vérifier si les données chargées correspondent à ce qui est attendu void dataIntegrityCheck() { // vérification du nombre de lignes // équipes int rowCount = this.table.getRowCount(); if (rowCount!=nombreEquipes) { // on gère seulement le cas où on a chargé plus de lignes que d'équipes voulues // le cas inverse n'est pas bloquant et se résoud tout seul if (rowCount>nombreEquipes) { // calcul de la différence int diff = rowCount - nombreEquipes; // suppression des dernières lignes jusqu'à revenir à l'équilibre for (int i = rowCount; i>rowCount-diff; i--) { this.table.removeRow(i-1); //println("Scoreboard.removeRow", i-1); } } } } void draw() { //if (!this.display) return; int count = 0; //int podium = 3; int margin = 60; float offsetX = this.posX; float offsetY = this.posY; float lastX = 0; rectMode(CORNER); fill(color(0, 0, 0, 100)); stroke(color(0, 0, 0)); strokeWeight(1); rect(this.posX, this.posY+20, this.width, this.height); // pour chaque score de 50 à 1 for (int i=50; i>0; i--) { // on limite aux 5 premières équipes if (count==5) break; // récupération des équipes à ce score Iterable rowsIterable = this.findEquipesByScore(i); ArrayList teams = new ArrayList(); for (TableRow row : rowsIterable) { teams.add(row.getString("equipe")); } // arrêter la boucle si on est hors du cadre d'affichage //if (offsetX-margin<=this.posX) break; // passer cette itération si aucune équipe à afficher if (teams.size()==0) continue; // affichage du score fill(color(0,0,0)); rect(offsetX, offsetY+20, 55, 50); fill(color(240, 240, 80)); stroke(color(0, 0, 0)); strokeWeight(1); textFont(quicksandFont, 40); String text = str(count+1); // correction de positionnement horizontal // selon largeur du texte //float localMarginX = (i<=9)? margin+14: (i>=40)? margin-8: margin; float localMarginX = count==0? 10: 0; // selon nombre d'équipes à afficher pour ce score // localMarginX = (teams.size()>1)? localMarginX+((teams.size()-1)*margin)/2: localMarginX; //fill(color(0, 250, 0)); text(text, offsetX+localMarginX, offsetY+margin); localMarginX = count==0? 20: 25; textFont(quicksandFont, 20); text = count==0? " er": "e"; text(text, offsetX+localMarginX, offsetY+margin-16); // affichage des équipes for(int j=0; j1)? localMarginX+((teams.size()-1)*margin)/2: localMarginX; fill(color(240, 240, 80)); circle(offsetX+subLocalMarginX, offsetY+(margin*2)-12, 50); fill(color(0, 0, 0)); textFont(quicksandFont, 32); // selon largeur du texte subLocalMarginX = (int(teams.get(j))<=9)? (int(teams.get(j))==1)? subLocalMarginX-6: subLocalMarginX-8: (int(teams.get(j))>=40)? subLocalMarginX-20: subLocalMarginX-15; text(teams.get(j), offsetX+subLocalMarginX, offsetY+(margin*2)); count++; } //line(offsetX-(margin*teams.size())-10, offsetY, offsetX-(margin*teams.size())-10, offsetY+this.height); lastX = offsetX+(margin*teams.size())-10; offsetX += margin*teams.size(); } noFill(); stroke(color(0, 0, 0)); //rect(lastX, this.posY, margin*count, this.height); } }