\documentclass[a4paper,12pt]{article}

% Packages
\usepackage[french]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{tabularx}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{eurosym}
\usepackage{epsfig}
\usepackage{stmaryrd}

% Title
\title{Pente : Interface Graphique}
\author{D.Moreaux}

% Document
\begin{document}
\maketitle
\section{PyGame-CE}
\subsection{Introduction}
La documentation officielle de PyGame-CE se trouve à l'adresse https://pyga.me/docs/

Important, dans le gestionnaire de packages, installer la version pygame-ce et non la version pygame.

L'exemple de programme de Othelle à http://cours.endor.be/2IN\_Python/Demo\_Code/othello.py permet de se faire
une idée de comment on peut gérer un plateau de jeu en PyGame (à noter que pour le moment, les différences entre
PyGame et PyGame-CE sont limitées)


\section{PyGame-GUI}
\subsection{Introduction}
La documentation officielle de PyGame\_GUI se trouve à l'adresse https://pygame-gui.readthedocs.io/en/latest/

Cette bibliothèque est prévue pour tourner avec la version PyGame-CE de PyGame et le package s'appelle pygame-gui.
Attention, l'import dans Python se fait avec \verb|import pygame_gui| avec un underscore et non un tiret.

L'utilisation de cette bibliothèque est assez simple : on crée un ui\_manager dans lequel on peut ajouter des
contrôles et les retirer (à l'aide de la fonction \verb|kill()|) selon les besoins.

Au niveau de la boucle principale, il faudra ajouter quelques appels à PyGame\_GUI (gestion des événements, tracé,
mise à jour,\dots) et la bibliothèque se chargera de la gestion des éléments GUI.

\subsection{Code de base}
Pour permettre à PyGame-GUI de fonctionner, il faut
\begin{itemize}
\item Après avoir défini le mode écran et récupéré la surface de ce dernier, instancier un UIManager. Il sera
    nécessaire de lui fournir les mêmes dimensions qu'au set_display. On pourra de plus indiquer un fichier JSON
    contenant le thème graphique si on désire en utiliser un
\item définir une horloge (\verb|clock = pygame.time.Clock()|) avant la boucle principale et au début de cette dernière,
    l'utiliser pour récupérer le temps écoulé \verb(dt=clock.tick(60) / 1000)
\item Dans la boucle de gestion des event, appeler la méthode \verb|process_event()| du UIManager avec l'événement
    en cours de traitement.
\item Avant de commencer le tracé, appeler la méthode \verb|update()| du UIManager avec le temps écoulé (dt)
\item Après les tracés (et avant le flip), appeler la méthode \verb|draw_ui()| du UIManager en lui passant la
    surface de l'écran
\end{itemize}

\begin{verbatim*}
import pygame
import pygame_gui

pygame.init()
screen = pygame.display.set_mode((800, 600))
background = pygame.Surface((800, 600))
background.fill(pygame.Color('#000000'))

manager = pygame_gui.UIManager((800, 600)) # UIManager

clock = pygame.time.Clock()
is_running = True
while is_running:
    time_delta = clock.tick(60)/1000.0
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            is_running = False
        manager.process_events(event) # Event

    manager.update(time_delta) # Update
    screen.blit(background, (0, 0))
    manager.draw_ui(window_surface) # Draw

    pygame.display.update()

\end{verbatim*}

\subsection{Events}
PyGameGUI ajoute une série d'Events qui peuvent être traités dans la boucle. Pour les détecter, on comparera
\verb|event.type| au nom de l'événement (de la forme \verb|pygame_gui.UI_...|)

La propriété \verb|ui_element| de l'event vaudra l'élément GUI ayant déclenché l'événement
\footnote{Quand on créera un élément dont on désire gérer les événements, on prendra soin de les sauver dans des
variables pour permettre la comparaison ultérieurement}

\begin{itemize}
    \item UI\_BUTTON\_PRESSED se déclenche lorsque l'on a cliqué et relaché le bouton de la souris sur l'élément.
    C'est l'équivalent du onclick du javascript. Par défaut, seul le clic gauche est pris en compte
    \item UI\_TEXT\_ENTRY\_CHANGED indique que le texte d'une zone d'entrée a été changé. On peut accéder au nouveau
    texte par la propriété \verb|text| de l'événement
    \item UI\_TEXT\_ENTRY\_FINISHED indique que l'on a enfoncé la touche Enter alors qu'on était en train d'éditer
    une zone d'entrée. De nouveau, le texte peut être récupéré dans l'event.
    \item UI\_DROP\_DOWN\_MENU\_CHANGED indique que l'on a changé la valeur d'une liste "drop-down". La propriété
    \verb|text| de l'objet event permet d'obtenir le nouveau texte choisi et la propriété \verb|selected_option_id|
    permet de retrouver l'ID de l'option s'il y en a une (sinon, on récupère le texte).
    \item \dots
\end{itemize}

Lorsque l'on utilise les boîtes de dialogue standard (sélection de fichier, confirmation,\dots), des événements sont
également générés lorsque l'on confirme un choix.

\subsection{Elements d'interface}
Différents objets peuvent être instanciés à l'aide de \verb|pygame_gui.elements.UI_...(...,manager=uimanager)| où le
dernier paramètre indique le UIManager associé.

La valeur retournée peut être sauvée dans une variable pour comparaison ultérieure dans le gestionnaire d'événements
ou pour effacer l'élément en appelant sa méthode \verb|kill()|.

On peut aussi activer et désactiver des éléments à l'aide des méthodes \verb|disable()| et \verb|enable()|.

La propriété \verb|relative_rect| est un \verb|pygame.Rect| indiquant la position et la taille de l'élement.

\begin{itemize}
    \item UILabel permet de mettre une étiquette texte. Le paramètre \verb|text| est une chaîne contenant le texte
    devant être affiché.
    \item UIButton permet de créer un bouton. Le paramètre \verb|text| contient le texte affiché dans le bouton. On
    peut utiliser le paramètre \verb|command| pour spécifier une fonction à exécuter lors du clic ou gérer
    l'événement dans la boucle d'événements.
    \item UIDropDownMenu permet de créer une liste "drop down". On précisera un paramètre \verb|options_list| qui
    contiendra une liste de chaînes proposées et \verb|starting_option| qui contiendra l'option de départ (son texte)
    .  Il est également possible de fournir une liste de paire de valeurs (texte et ID) pour les options.
    \item UITextEntryLine permet de créer une zone d'entrée texte. \verb|initial_text| contiendra le texte initial
    s'il est non vide. La méthode \verb|get_text()| permet de récupérer le texte entré.

\end{itemize}

On peut aussi ajouter une propriété \verb|object_id="#..."| à un élément pour faire un lien avec le thème.

La méthode \verb|set_text()| permet de changer le texte d'éléments tels que UILabel, UIButton, UITextEntryLine,\dots




\end{document}