Aller au contenu

Un compteur en Rust

📚 Exemple minimal egui : un compteur + un champ texte

️️⚙️ Dépendances à ajouter dans Cargo.toml :

[dependencies]
   eframe = "0.36.1"

💻 Compilation / lancement :

cargo run

Changement en 2026 :

Depuis eframe 0.34, le trait App a changé : La méthode à implémenter s'appelle désormais ui, et non plus update. Elle reçoit directement un &mut egui::Ui (et non plus un &egui::Context). C'est pour cela que CentralPanel::default().show(...) prend ci-dessous ui` en premier argument, et non ctx.

💻 La source main.rs :

use eframe::egui;

// -----------------------------------------------------------------
// 1. L'état de l'application : tout ce qui doit "survivre" entre
//    deux images (frames) est stocké ici. Rien d'autre n'est
//    mémorisé ailleurs : c'est la clé du mode immédiat.
// -----------------------------------------------------------------
struct MonApplication {
    compteur: i32,
    nom: String,
}

// Valeurs par défaut au démarrage
impl Default for MonApplication {
    fn default() -> Self {
        Self {
            compteur: 0,
            nom: String::new(),
        }
    }
}

// -----------------------------------------------------------------
// 2. Le trait eframe::App : une seule méthode à implémenter, ui,
//    appelée à chaque frame (généralement 60 fois par seconde).
//    On y décrit à la fois l'état ET l'apparence : pas de séparation
//    entre "dessiner" et "réagir aux clics", tout est au même endroit.
//    Depuis eframe 0.34, cette méthode reçoit un &mut egui::Ui
//    directement (et non plus un &egui::Context comme avant).
// -----------------------------------------------------------------
impl eframe::App for MonApplication {
    fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
        egui::CentralPanel::default().show(ui, |ui| {
            ui.heading("Petit exemple egui");

            ui.separator();

            // --- Compteur ---
            ui.horizontal(|ui| {
                if ui.button("-1").clicked() {
                    self.compteur -= 1;
                }
                ui.label(format!("Compteur : {}", self.compteur));
                if ui.button("+1").clicked() {
                    self.compteur += 1;
                }
            });

            if ui.button("Réinitialiser").clicked() {
                self.compteur = 0;
            }

            ui.separator();

            // --- Champ texte ---
            ui.horizontal(|ui| {
                ui.label("Votre prénom :");
                ui.text_edit_singleline(&mut self.nom);
            });

            if !self.nom.is_empty() {
                ui.label(format!("Bonjour, {} !", self.nom));
            }
        });
    }
}

// -----------------------------------------------------------------
// 3. Point d'entrée : on crée la fenêtre et on lance la boucle
//    d'événements. eframe se charge du reste (rendu, redraw, etc.)
// -----------------------------------------------------------------
fn main() -> eframe::Result<()> {
    let options = eframe::NativeOptions::default();
    eframe::run_native(
        "Exemple egui",
        options,
        Box::new(|_cc| Ok(Box::new(MonApplication::default()))),
    )
}