Let Texte/Titre elements bind directly to a single row of another object
Adds a "Donnée liée" settings group to Texte/Titre: pick an object, optionally match it to the current game state via 1-2 filter conditions (same engine as the data-repeater's filter, including {{Objet.champ}} cross-references), and use {{champ}} in the text content to show a field from that one matching row. Unlike the data repeater — built for showing a list of rows — this covers displaying a single computed value (e.g. the objective of the level matching the game's current parcours/level) without wrapping it in a repeater.
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
from ..controls.c_text import c_text
|
||||
from ..controls.c_select import c_select
|
||||
from ...flow.constants import CONDITION_OPERATORS
|
||||
|
||||
# Permet à un Texte/Titre d'afficher directement la valeur d'un champ d'un
|
||||
# AUTRE objet de données, sans avoir besoin de le poser dans un Répéteur —
|
||||
# utile pour une valeur unique calculée (ex: l'objectif du niveau en cours)
|
||||
# plutôt qu'une liste. La ligne affichée est celle qui correspond aux 1 ou 2
|
||||
# filtres réglés ci-dessous (mêmes réglages, même moteur que ceux du
|
||||
# Répéteur de données — voir filter_repeater_rows.py) ; sans filtre, c'est la
|
||||
# ligne la plus récente de l'objet choisi (convention déjà utilisée par la
|
||||
# Jauge pour un objet "état de partie" qui ne garde qu'une seule ligne).
|
||||
DATA_BINDING_CONTROLS = [
|
||||
c_select("data_definition_id", "Lier à un objet de données (pour {{champ}} ci-dessus)",
|
||||
"attr:_data_definition_id", [("", "(sélectionner un objet)")], default="", group="Donnée liée"),
|
||||
c_text("data_filtre_champ", "Trouver la ligne où ce champ",
|
||||
"attr:_data_filtre_champ", placeholder="ex. number", default="", group="Donnée liée"),
|
||||
c_select("data_filtre_operateur", "...est", "attr:_data_filtre_operateur", CONDITION_OPERATORS, default="egal", group="Donnée liée"),
|
||||
c_text("data_filtre_valeur", "...cette valeur, ou {{NomObjet.champ}} pour une donnée qui change en cours de partie",
|
||||
"attr:_data_filtre_valeur", placeholder="ex. 3 ou {{game.current_level}}", default="", group="Donnée liée"),
|
||||
c_text("data_filtre2_champ", "ET (optionnel) : ce 2ᵉ champ",
|
||||
"attr:_data_filtre2_champ", placeholder="ex. parcour_id", default="", group="Donnée liée"),
|
||||
c_select("data_filtre2_operateur", "...est", "attr:_data_filtre2_operateur", CONDITION_OPERATORS, default="egal", group="Donnée liée"),
|
||||
c_text("data_filtre2_valeur", "...cette valeur, ou {{NomObjet.champ}}",
|
||||
"attr:_data_filtre2_valeur", placeholder="ex. 1 ou {{game.current_parcours}}", default="", group="Donnée liée"),
|
||||
]
|
||||
@@ -24,7 +24,7 @@ def controls_with_values(slug, el):
|
||||
result = []
|
||||
for control in meta.get("controls", []):
|
||||
control = dict(control)
|
||||
if control["key"] == "definition_id":
|
||||
if control["key"] in ("definition_id", "data_definition_id"):
|
||||
defs = db.list_definitions(slug)
|
||||
control["options"] = [("", "(sélectionner un objet)")] + [(str(d["id"]), d["name"]) for d in defs]
|
||||
if control["key"] == "template_type_id":
|
||||
|
||||
@@ -8,6 +8,7 @@ from .controls.c_toggle_token import c_toggle_token
|
||||
from .controls.c_align import c_align
|
||||
from .controls.c_select import c_select
|
||||
from .control_groups.text_style_controls_extra import TEXT_STYLE_CONTROLS_EXTRA
|
||||
from .control_groups.data_binding_controls import DATA_BINDING_CONTROLS
|
||||
from .font_options import FONT_OPTIONS
|
||||
from ..flow.constants import CONDITION_OPERATORS
|
||||
|
||||
@@ -16,7 +17,8 @@ WIDGETS = {
|
||||
"label": "Texte", "icon": "📝", "tag": "p", "has_content": True,
|
||||
"w": 40, "h": 10, "default_content": "Texte du paragraphe.",
|
||||
"controls": [
|
||||
c_textarea("content", "Texte", "content", default="Texte du paragraphe.", group="Contenu"),
|
||||
c_textarea("content", "Texte — {{champ}} affiche la valeur de ce champ sur la ligne trouvée ci-dessous", "content", default="Texte du paragraphe.", group="Contenu"),
|
||||
] + DATA_BINDING_CONTROLS + [
|
||||
c_slider("font-size", "Taille du texte", "style:font-size", min=10, max=64, default=16, group="Texte"),
|
||||
c_color("color", "Couleur du texte", "style:color", "#e8eaf0", group="Texte"),
|
||||
c_align("text-align", "Alignement", "style:text-align", group="Texte"),
|
||||
@@ -30,9 +32,10 @@ WIDGETS = {
|
||||
"label": "Titre", "icon": "🔠", "tag": None, "has_content": True,
|
||||
"w": 55, "h": 10, "default_content": "Titre",
|
||||
"controls": [
|
||||
c_textarea("content", "Texte", "content", default="Titre", group="Contenu"),
|
||||
c_textarea("content", "Texte — {{champ}} affiche la valeur de ce champ sur la ligne trouvée ci-dessous", "content", default="Titre", group="Contenu"),
|
||||
c_select("niveau", "Importance du titre", "attr:_niveau",
|
||||
[("1", "Très grand — titre principal"), ("2", "Grand"), ("3", "Moyen")], default="2", group="Contenu"),
|
||||
] + DATA_BINDING_CONTROLS + [
|
||||
c_slider("font-size", "Taille du texte", "style:font-size", min=14, max=80, default=32, group="Texte"),
|
||||
c_color("color", "Couleur du texte", "style:color", "#e8eaf0", group="Texte"),
|
||||
c_align("text-align", "Alignement", "style:text-align", default="left", group="Texte"),
|
||||
|
||||
Reference in New Issue
Block a user