Introduction à l'habillage des interfaces graphiques

Il est essentiel qu'un jeu fournisse à ses joueurs une interface utilisateur claire, informative et agréable à l'œil. Bien que les nœuds Control soient dotés d'un aspect fonctionnel correct, il est toujours possible de les rendre uniques et de les personnaliser. À cette fin, le moteur Godot comprend un système d'habillage de l'interface graphique (ou theming), qui vous permet de personnaliser l'apparence de chaque control de votre interface utilisateur, y compris vos controls personnalisés.

Voici un exemple de ce système en action — un jeu dont l'interface graphique est radicalement différente du thème par défaut du moteur :

../../_images/tank-kings-by-winterpixel-games.png

Un écran "Gear Up!" dans Tank Kings, avec l'aimable autorisation de Winterpixel Games

En plus de permettre de donner un look unique a votre jeu, ce système permet aussi aux développeurs d'apporter des options de customisation aux utilisateurs finaux, y compris des réglages d'accessibilité. Les thèmes d'interface utilisateur sont appliqués en cascade (ils se propagent depuis le nœud Control parent a ses enfants), ce qui signifie que qu'un réglage de police d'écriture ou un ajustement pour les utilisateurs daltoniens peut être appliqué a un seul endroit et ainsi affecter l'entièreté de l'arbre d'interface utilisateur. Bien sur, ce système peut aussi être utilisé dans le cadre du gameplay : votre jeu basé sur son héros peut changer de style d'interface en fonction du personnage sélectionné par le joueur, ou vous pouvez donner différentes saveurs d'interface à chaque groupe dans un jeu en équipe.

Les bases des thèmes

Le système d'habillage est basé sur la ressource Theme. Chaque projet Godot possède un thème par défaut qui contient les paramètres utilisés par les nœuds de contrôle intégrés. C'est ce qui donne aux contrôles leur aspect distinct. Cependant, un thème décrit seulement la configuration, et c'est toujours le travail de chaque contrôle individuel d'utiliser cette configuration comme il veut pour s'afficher. Il est important de s'en souvenir quand vous implémentez vos propres contrôles personnalisés.

Note

L'éditeur Godot lui-même utilise le thème par défaut. Mais il n'a pas la même apparence qu'un projet Godot, parce qu'il applique son propre thème fortement personnalisé par-dessus le thème par défaut. En principe, cela fonctionne exactement comme dans votre jeu, comme expliqué ci-dessous.

Éléments de thème

La configuration qui est stockée dans un thème est constituée d'éléments de thème. Chaque élément possède un nom unique et doit être de l'un des types de données suivants :

  • Color

    Une valeur de couleur, qui est souvent utilisée pour les polices et les arrière-plans. Les couleurs peuvent également servir à la modulation des contrôles et des icônes.

  • Constant

    Un nombre entier, qui peut être utilisé soit pour les propriétés numériques des contrôles (comme la séparation des éléments dans un BoxContainer), soit pour des indicateurs booléens (comme l'affichage de lignes de relation dans un Tree).

  • Font

    Une ressource de police, qui est utilisée par les contrôles pour afficher du texte. Les polices contiennent la plupart des paramètres de rendu du texte, à l'exception de sa taille et de sa couleur. En plus, l'alignement et la direction du texte sont contrôlés par des contrôles individuels.

  • Icon

    Une ressource de texture, qui est normalement utilisée pour afficher une icône (sur un Button, par exemple).

  • StyleBox

    Une ressource StyleBox, une collection d'options de configuration qui définissent la façon dont un panneau doit être affiché. Ce n'est pas limité au contrôle Panel, les boîtes de style sont utilisées par de nombreux contrôles pour leurs arrière-plans et leurs overlays.

Types de thèmes

Pour faciliter l'organisation de ses éléments, chaque thème est séparé en types, et chaque élément doit appartenir à un seul type. En d'autres termes, chaque élément du thème est défini par son nom, son type de données et son type de thème. Cette combinaison doit être unique au sein du thème. Par exemple, il ne peut y avoir deux éléments de couleur nommés font_color dans un type appelé Label, mais il peut y avoir un autre élément font_color dans un type LineEdit.

Le thème Godot par défaut est livré avec plusieurs types de thèmes déjà définis, un pour chaque nœud control intégré qui utilise l'habillage de l'interface utilisateur. L'exemple ci-dessus contient des éléments de thème présents dans le thème par défaut. Vous pouvez vous référer à la section Theme Properties dans la référence de classe de chaque control pour voir quels éléments sont disponibles pour lui et ses classes enfants.

Note

Les classes enfant peuvent utiliser les éléments de thème définis pour leur classe parent (Button et ses dérivés en étant un bon exemple). En fait, chaque contrôle peut utiliser chaque élément de thème de tout type de thème, s'il en a besoin (mais pour la clarté et la prévisibilité, nous essayons d'éviter cela dans le moteur).

Il est important de se rappeler que pour les classes enfant, ce processus est automatisé. Lorsqu'un control intégré demande un élément du thème, il peut omettre le type de thème et le nom de sa classe sera utilisé à la place. En outre, les noms de classe de ses classes parentes seront également utilisés à leur tour. Cela permet aux modifications apportées à la classe mère, comme Button, d'affecter toutes les classes dérivées sans qu'il soit nécessaire de personnaliser chacune d'entre elles.

Vous pouvez également définir vos propres types de thèmes et personnaliser les controls intégrés et vos propres controls. Les controls intégrés n'ayant aucune connaissance de vos types de thèmes personnalisés, vous devez utiliser des scripts pour accéder à ces éléments. Tous les nœuds de control disposent de plusieurs méthodes permettant d'extraire des éléments de thème du thème qui leur est appliqué. Ces méthodes acceptent le type de thème comme l'un des arguments.

var accent_color = get_color("accent_color", "MyType")
label.add_color_override("font_color", accent_color)

Personnalisation d'un contrôle

Chaque nœud control peut être personnalisé directement sans l'utilisation de thèmes. C'est ce qu'on appelle les surcharges locales. Chaque propriété de thème de la référence de classe du control peut être remplacée directement sur le control lui-même, en utilisant le dock de l'inspecteur ou des scripts. Cela permet d'apporter des modifications granulaires à une partie particulière de l'interface utilisateur, tout en n'affectant rien d'autre dans le projet, y compris les enfants de ce control.

../../_images/themecheck.png

Les surcharges locales sont moins utiles pour l'aspect visuel de votre interface utilisateur, surtout si vous recherchez la cohérence. Cependant, pour les nœuds de mise en page, elles sont essentielles. Des nœuds tels que BoxContainer et GridContainer utilisent des constantes de thème pour définir la séparation entre leurs enfants, et MarginContainer stocke ses marges personnalisables dans ses éléments de thème.

Lorsqu'un control dispose d'une surcharge d'élément de thème local, c'est la valeur qu'il utilise. Les valeurs fournies par le thème sont ignorées.

Personnaliser un projet

Par défaut, chaque projet adopte le thème de projet par défaut fourni par Godot. Le thème par défaut lui-même est constant et ne peut être modifié, mais ses éléments peuvent être remplacés par un thème personnalisé. Les thèmes personnalisés peuvent être appliqués de deux façons : en tant que paramètre de projet et en tant que propriété de nœud dans l'arbre des nœuds control.

Il existe deux paramètres de projet qui peuvent être ajustés pour affecter l'ensemble de votre projet : gui/theme/custom vous permet de définir un thème personnalisé pour l'ensemble du projet, et gui/theme/custom_font fait de même pour la police de secours par défaut. Lorsqu'un élément de thème est demandé par un nœud control, le thème personnalisé du projet, s'il est présent, est vérifié en premier. Le thème par défaut n'est vérifié que si l'élément n'est pas présent.

Cela vous permet de configurer l'apparence par défaut de chaque control de Godot avec une seule ressource de thème, mais vous pouvez aller plus loin. Chaque nœud control possède également une propriété theme, qui vous permet de définir un thème personnalisé pour la branche des nœuds commençant par ce control. Cela signifie que le control et tous ses enfants, et leurs enfants à leur tour, vérifieront d'abord cette ressource de thème personnalisé avant de se rabattre sur le projet et les thèmes par défaut.

Note

Au lieu de modifier le paramètre du projet, vous pouvez définir la ressource du thème personnalisé sur le nœud control le plus profond de toute votre branche d'interface utilisateur pour obtenir presque le même effet. Alors que dans le projet en cours d'exécution, il se comportera comme prévu, les scènes individuelles s'afficheront toujours en utilisant le thème par défaut lors de la prévisualisation ou de l'exécution directe. Pour résoudre ce problème, vous pouvez définir la même ressource de thème à la racine du control de chaque scène individuelle.

Par exemple, vous pouvez avoir un certain style pour les boutons dans le thème de votre projet, mais vouloir un aspect différent pour les boutons à l'intérieur d'une boîte de dialogue contextuelle. Vous pouvez définir une ressource de thème personnalisée pour le control racine de votre fenêtre contextuelle et définir un style différent pour les boutons dans cette ressource. Tant que la chaîne de nœuds de control entre la racine de la fenêtre popup et les boutons est ininterrompue, ces derniers utiliseront les styles définis dans la ressource de thème la plus proche d'eux. Tous les autres controls seront toujours stylisés à l'aide du thème du projet et des styles du thème par défaut.

En résumé, pour un control arbitraire, la recherche d'un élément de thème ressemblerait à ceci :

  1. Vérifier s'il existe des surcharges locales du même type de données et du même nom.

  2. Utilisation du nom de la classe du control et des noms des classes parentes :

    1. Vérifie chaque contrôle en commençant par lui-même et regarde s'il utilise un thème ;

    2. Si c'est le cas, recherchez dans ce thème l'élément correspondant ayant le même nom, les mêmes données et le même type de thème ;

    3. S'il n'y a pas de thème personnalisé ou s'il ne possède pas l'élément, passez au control parent ;

    4. Répétez les étapes a-c. jusqu'à ce que la racine de l'arbre soit atteinte, ou qu'un nœud de non-control soit atteint.

  3. En utilisant le nom de la classe du control, vérifiez le thème du projet, s'il est présent.

  4. Utilisation du nom de la classe du control pour vérifier le thème par défaut.

Même si l'élément n'existe dans aucun thème, une valeur par défaut correspondante pour ce type de données sera renvoyée.

Au-delà des controls

Naturellement, les thèmes sont un type de ressource idéal pour stocker la configuration d'un élément visuel. Bien que la prise en charge des thèmes soit intégrée aux nœuds control, d'autres nœuds peuvent également les utiliser, comme toute autre ressource.

Un exemple d'utilisation des thèmes pour autre chose que des controls peut être une modulation des sprites pour les mêmes unités dans différentes équipes dans un jeu de stratégie. Une ressource de thème peut définir une collection de couleurs, et les sprites (avec l'aide de scripts) peuvent utiliser ces couleurs pour dessiner la texture. Le principal avantage est que vous pouvez créer des thèmes différents en utilisant les mêmes éléments de thème pour les équipes rouges, bleues et vertes, et les intervertir avec un seul changement de ressource.