Créer une calculatrice d’addition simple avec ImGui

Nous allons implémenter une fonction d’addition : deux champs de saisie numérique, un signe + au milieu et un bouton égal. Après avoir saisi deux nombres et cliqué sur le signe =, le résultat du calcul s’affichera dans un troisième champ de saisie.

La fonctionnalité est très basique, mais elle nous permet de découvrir les composants de formulaire fondamentaux d’ImGui.

Voici d’abord une capture d’écran du programme en cours d’exécution

C’est un exemple minimaliste. La majeure partie du code est identique à l’exemple du cours précédent, seule la partie du rendu de l’interface change. Nous avons aussi ajouté quelques variables pour stocker les valeurs numériques et activé le thème clair, afin de se rapprocher des applications GUI classiques sur ordinateur.

#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")

#include <GLFW/glfw3.h>
#include "imgui.h"
#include "backends/imgui_impl_glfw.h"
#include "backends/imgui_impl_opengl3.h"
#include <cstdio>

int main()
{
    if (!glfwInit())
    {
        printf("Échec de l'initialisation de GLFW\n");
        return -1;
    }

    const char* glsl_version = "#version 330";
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow* window = glfwCreateWindow(500, 200, "Calculatrice Addition", nullptr, nullptr); // Taille et titre de la fenêtre
    if (!window)
    {
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);

    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO();
	ImGui::StyleColorsLight(); // Activer le thème clair

    ImGui_ImplGlfw_InitForOpenGL(window, true);
    ImGui_ImplOpenGL3_Init(glsl_version);

    // Variables globales de la calculatrice
    float num1 = 0.0f;    // Premier nombre à additionner
    float num2 = 0.0f;    // Second nombre à additionner
    float result = 0.0f;  // Somme des deux nombres

    while (!glfwWindowShouldClose(window))
    {
        glfwPollEvents();

        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();

        ImGui::SetNextWindowPos(ImVec2(0, 0));
        ImGui::SetNextWindowSize(io.DisplaySize);

        ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration
            | ImGuiWindowFlags_NoMove
            | ImGuiWindowFlags_NoResize
            | ImGuiWindowFlags_NoSavedSettings;

        ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
        ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);

        ImGui::Begin("Panneau de contrôle", nullptr, window_flags);

        // Titre de la calculatrice
        ImGui::Text("Veuillez saisir deux nombres"); // Texte statique, occupe une ligne entière
	ImGui::Spacing();// Ajouter un espace vertical

        // Premier champ de saisie, largeur 120px
	ImGui::SetNextItemWidth(120);// Définit la largeur du widget suivant, ne s'affiche pas seul
	ImGui::InputFloat("##num1", &num1);// Champ de saisie flottant lié à num1, étiquette masquée, une ligne seule

        // Afficher le signe plus sur la même ligne
	ImGui::SameLine(); // Le widget suivant s'affiche sur la même ligne ; sans cela, saut de ligne automatique
	ImGui::Text(" + "); // Signe plus sur la même ligne que le premier champ

        // Second champ de saisie numérique
	ImGui::SameLine(); // À appeler avant chaque widget à aligner horizontalement
        ImGui::SetNextItemWidth(120);// Définir la largeur du second champ
        ImGui::InputFloat("##num2", &num2);

        // Bouton égal, déclenche l'addition au clic
        ImGui::SameLine();
        if (ImGui::Button(" = ", ImVec2(40, 0)))
        {
            // Calculer la somme et stocker dans la variable résultat
            result = num1 + num2;
        }

        // Champ résultat en lecture seule, affichage à deux décimales, modification manuelle interdite
        ImGui::SameLine();
        ImGui::SetNextItemWidth(180);
        ImGui::InputFloat("##result", &result, 0.0f, 0.0f, "%.2f", ImGuiInputTextFlags_ReadOnly);

        ImGui::End();

	// Restaurer les styles temporaires sauvegardés
        ImGui::PopStyleVar(2);

        ImGui::Render();
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        glViewport(0, 0, width, height);
        glClearColor(0.12f, 0.12f, 0.12f, 1.f);
        glClear(GL_COLOR_BUFFER_BIT);
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

        glfwSwapBuffers(window);
    }

    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();
    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;
}Langage du code : C++ (cpp)

Pour activer le thème clair, il suffit de modifier cette ligne : ImGui::StyleColorsLight(); // Passer l’interface en thème clair

Pour personnaliser le titre et la taille de la fenêtre, modifiez cette ligne : GLFWwindow* window = glfwCreateWindow(400, 60, « Calculatrice Addition », nullptr, nullptr); // Définir largeur, hauteur et titre de fenêtre

ImGui::Text("Veuillez saisir deux nombres");

ImGui::Spacing(); // Ajouter un espace vertical entre le titre et les champs de saisieLangage du code : PHP (php)

Cette ligne affiche un texte statique sur la première ligne, puis insère un espace vertical sur la ligne suivante.

Consultez les commentaires du code ci-dessus pour les autres propriétés. Par défaut, Text, InputFloat et Button occupent chacun une ligne complète. Si vous voulez éviter le saut de ligne, appelez ImGui::SameLine(); avant de dessiner chaque widget à aligner horizontalement.

Utilisez SetNextItemWidth() si vous devez définir manuellement la largeur du prochain composant d’interface.

Fonctionnement du clic sur bouton

if (ImGui::Button(" = ", ImVec2(40, 0)))
 {
            // Calculer la somme des deux valeurs et l'affecter au résultat
            result = num1 + num2;
 }Langage du code : C++ (cpp)

Ici, ImGui::Button( » = « , ImVec2(40, 0)) dessine un bouton interactif. Le premier paramètre est le texte affiché, le second définit sa largeur et hauteur ; une hauteur à 0 signifie hauteur automatique adaptée au widget.

Cette fonction ne renvoie true que lors d’un clic complet (appui + relâchement de la souris sur le bouton) ; elle renvoie false dans tous les autres cas. Quand la valeur retournée est true, tout le code entre les accolades {} s’exécute.

Imaginez un processus de boucle continu : l’interface se rafraîchit sans arrêt, tout le code dans la boucle while s’exécute à chaque rafraîchissement. Si l’utilisateur n’interagit pas, l’affichage reste identique à chaque frame. Si un clic survient sur le bouton pendant une frame, ImGui::Button() renvoie true et le code de calcul s’exécute immédiatement.

Le code du bouton additionne les deux valeurs liées aux champs de saisie, stocke la somme dans la variable result, puis dessine le champ résultat sur la même ligne.

ImGui::SameLine();
ImGui::SetNextItemWidth(180);
ImGui::InputFloat("##result", &result, 0.0f, 0.0f, "%.2f", ImGuiInputTextFlags_ReadOnly);Langage du code : C++ (cpp)

Ces instructions restent sur la même ligne que le bouton et affichent la somme calculée dans le troisième champ de saisie, configuré en lecture seule.

Une fois le rendu d’une frame terminé, le rafraîchissement suivant conservera le résultat précédent si aucune nouvelle action n’est effectuée.

Ce mécanisme de rendu est identique à celui des jeux vidéo, dont les animations reposent sur ce même système de rafraîchissement continu des images.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *