first commit
Build and deploy / build-and-push (push) Successful in 17s
Build and deploy / deploy (push) Successful in 10s

This commit is contained in:
william
2026-08-21 16:23:49 +02:00
committed by william
commit 3f4ebc4527
248 changed files with 10180 additions and 0 deletions
@@ -0,0 +1 @@
"""Groupes de réglages ("controls") réutilisés par plusieurs widgets."""
@@ -0,0 +1,20 @@
from ..controls.c_slider import c_slider
from ..controls.c_color import c_color
from ..controls.c_select import c_select
from ..border_style_options import BORDER_STYLE_OPTIONS
# Les épaisseurs "par côté" ci-dessous sont volontairement placées APRÈS
# "border-width" (tous les côtés) dans cette même liste : pour une même
# propriété CSS, la déclaration qui apparaît EN DERNIER dans l'attribut
# style l'emporte — un réglage par côté prime donc sur le réglage global
# quand les deux sont utilisés ensemble. La couleur et le style de bordure
# restent communs aux 4 côtés.
BORDER_CONTROLS = [
c_slider("border-width", "Épaisseur de la bordure, tous les côtés", "style:border-width", min=0, max=20, default=0, group="Bordure"),
c_color("border-color", "Couleur de la bordure", "style:border-color", "#2b3140", group="Bordure"),
c_select("border-style", "Style de la bordure", "style:border-style", BORDER_STYLE_OPTIONS, default="solid", group="Bordure"),
c_slider("border-top-width", "Épaisseur — haut", "style:border-top-width", min=0, max=20, default=0, group="Bordure"),
c_slider("border-right-width", "Épaisseur — droite", "style:border-right-width", min=0, max=20, default=0, group="Bordure"),
c_slider("border-bottom-width", "Épaisseur — bas", "style:border-bottom-width", min=0, max=20, default=0, group="Bordure"),
c_slider("border-left-width", "Épaisseur — gauche", "style:border-left-width", min=0, max=20, default=0, group="Bordure"),
]
@@ -0,0 +1,21 @@
from ..controls.c_text import c_text
# 3.1 (Confort) — interactions au survol : mécanisme générique, disponible
# sur TOUS les widgets (via UNIVERSAL_CONTROLS), pour révéler un texte
# différent quand le joueur survole l'élément avec la souris — le cas
# d'usage documenté : survoler un nom révèle l'adresse réelle, survoler un
# lien révèle l'URL réelle. Laisser vide = aucun changement au survol (donc
# aucune régression sur les jeux existants, dont l'attribut est absent).
# Rendu : voir render_element_html.py (attribut data-hover-text) et
# bindHoverTexts() dans templates/play.html (échange du texte au survol,
# ignore volontairement les éléments qui ont des enfants — conteneurs — pour
# ne jamais écraser une mise en page imbriquée).
HOVER_CONTROLS = [
c_text(
"survol_texte",
"Texte affiché au survol de la souris",
"attr:_survol_texte",
placeholder="ex. mathilde.d@forgebase.fr, https://vrai-lien.exemple...",
group="Survol",
),
]
@@ -0,0 +1,44 @@
from ..controls.c_preset import c_preset
from ..controls.c_checkbox import c_checkbox
from ..controls.c_slider import c_slider
LAYOUT_CONTROLS = [
c_preset(
"disposition_interne", "Disposition interne",
[
("libre", "Empilement libre", {"display": "", "flex-direction": ""}),
("ligne", "Alignés côte à côte", {"display": "flex", "flex-direction": "row"}),
("ligne_inverse", "Alignés côte à côte, ordre inversé", {"display": "flex", "flex-direction": "row-reverse"}),
("colonne", "Alignés les uns sous les autres", {"display": "flex", "flex-direction": "column"}),
("colonne_inverse", "Alignés les uns sous les autres, ordre inversé", {"display": "flex", "flex-direction": "column-reverse"}),
],
default="libre", group="Disposition",
),
c_preset(
"alignement_transversal", "Alignement transversal",
[
("etire", "Étirés pour remplir", {"align-items": ""}),
("debut", "Alignés au début", {"align-items": "flex-start"}),
("centre_t", "Centrés", {"align-items": "center"}),
("fin", "Alignés à la fin", {"align-items": "flex-end"}),
],
default="etire", group="Disposition",
),
c_preset(
"alignement_principal", "Répartition",
[
("debut_p", "Regroupés au début", {"justify-content": ""}),
("centre_p", "Regroupés au centre", {"justify-content": "center"}),
("fin_p", "Regroupés à la fin", {"justify-content": "flex-end"}),
("espace_entre", "Espacement égal entre eux", {"justify-content": "space-between"}),
("espace_autour", "Espacement égal autour de chacun", {"justify-content": "space-around"}),
("espace_uniforme", "Espacement totalement uniforme", {"justify-content": "space-evenly"}),
],
default="debut_p", group="Disposition",
),
c_checkbox(
"flex-wrap", "Autoriser le retour à la ligne si ça ne tient pas",
"style:flex-wrap", true_value="wrap", false_value="nowrap", default=False, group="Disposition",
),
c_slider("gap", "Espace entre les éléments", "style:gap", min=0, max=40, default=8, group="Disposition"),
]
@@ -0,0 +1,16 @@
from ..controls.c_slider import c_slider
# Taille fixe (en pixels), surtout utile pour un élément posé À L'INTÉRIEUR
# d'un conteneur/répéteur/groupe de champs : par défaut, ces éléments
# remplissent la largeur disponible et s'ajustent en hauteur à leur contenu
# (voir _style_string) — 0 garde ce comportement automatique ; une valeur
# non nulle impose une taille fixe (ex: une image de 120px de large dans une
# ligne, pour que "Espacement égal entre eux"/"autour"/"uniforme" sur le
# conteneur parent ait un effet visible, ce qui n'est pas le cas tant que
# chaque élément remplit 100% de la largeur).
SIZE_OVERRIDE_CONTROLS = [
c_slider("child-width", "Largeur fixe", "style:width",
min=0, max=1000, default=0, group="Taille dans le conteneur"),
c_slider("child-height", "Hauteur fixe", "style:height",
min=0, max=1000, default=0, group="Taille dans le conteneur"),
]
@@ -0,0 +1,20 @@
from ..controls.c_slider import c_slider
# Les réglages "par côté" sont volontairement placés APRÈS les réglages
# globaux ci-dessous dans cette même liste : le style HTML final est généré
# dans cet ordre, et pour une même propriété CSS (ex. padding-top vs
# padding), la déclaration qui apparaît EN DERNIER dans l'attribut style
# l'emporte — donc un réglage par côté prime bien sur le réglage global s'il
# est utilisé en plus.
SPACING_CONTROLS = [
c_slider("padding", "Marge intérieure — tous les côtés", "style:padding", min=0, max=60, default=0, group="Espacement"),
c_slider("margin", "Marge extérieure — tous les côtés", "style:margin", min=0, max=60, default=0, group="Espacement"),
c_slider("padding-top", "Padding — haut", "style:padding-top", min=0, max=60, default=0, group="Espacement"),
c_slider("padding-right", "Padding — droite", "style:padding-right", min=0, max=60, default=0, group="Espacement"),
c_slider("padding-bottom", "Padding — bas", "style:padding-bottom", min=0, max=60, default=0, group="Espacement"),
c_slider("padding-left", "Padding — gauche", "style:padding-left", min=0, max=60, default=0, group="Espacement"),
c_slider("margin-top", "Margin — haut", "style:margin-top", min=0, max=60, default=0, group="Espacement"),
c_slider("margin-right", "Margin — droite", "style:margin-right", min=0, max=60, default=0, group="Espacement"),
c_slider("margin-bottom", "Margin — bas", "style:margin-bottom", min=0, max=60, default=0, group="Espacement"),
c_slider("margin-left", "Margin — gauche", "style:margin-left", min=0, max=60, default=0, group="Espacement"),
]
@@ -0,0 +1,6 @@
from ..controls.c_select import c_select
from ..font_options import FONT_OPTIONS
TEXT_STYLE_CONTROLS_EXTRA = [
c_select("font-family", "Police de caractère", "style:font-family", FONT_OPTIONS, default="inherit", group="Texte"),
]
@@ -0,0 +1,8 @@
from ..controls.c_scale import c_scale
from .visibility_control import VISIBILITY_CONTROL
from .size_override_controls import SIZE_OVERRIDE_CONTROLS
from .spacing_controls import SPACING_CONTROLS
from .border_controls import BORDER_CONTROLS
from .hover_controls import HOVER_CONTROLS
UNIVERSAL_CONTROLS = [VISIBILITY_CONTROL] + SIZE_OVERRIDE_CONTROLS + SPACING_CONTROLS + BORDER_CONTROLS + [c_scale()] + HOVER_CONTROLS
@@ -0,0 +1,16 @@
from ..controls.c_preset import c_preset
VISIBILITY_CONTROL = c_preset(
"visibilite", "Visibilité",
[
# "display" n'est volontairement pas touché par "visible" / "invisible" :
# un conteneur en disposition ligne/colonne (flex) doit garder son
# display:flex quand il redevient visible — seul "masqué" doit
# explicitement forcer display:none (et gagne, car ce réglage est
# appliqué après la disposition interne lors de l'enregistrement).
("visible", "Visible normalement", {"visibility": ""}),
("masque", "Masqué — n'occupe plus de place", {"display": "none", "visibility": ""}),
("invisible", "Invisible — garde sa place", {"visibility": "hidden"}),
],
default="visible", group="Disposition",
)