diff --git a/screens/flow/constants.py b/screens/flow/constants.py index 84fe0536..c06645d3 100644 --- a/screens/flow/constants.py +++ b/screens/flow/constants.py @@ -13,6 +13,15 @@ TRIGGER_EVENTS = [ ("clic", "Au clic"), ("soumission", "À la soumission"), + # 3.1 (Confort) — interactions au survol, reconstruit comme déclencheur + # de flow (au lieu d'un réglage statique dans le panneau de propriétés, + # voir universal_controls.py) : "survol" et "fin_survol" sont deux + # déclencheurs distincts et explicites (comme "Au clic"), sans effet + # implicite — un créateur qui veut qu'un texte affiché au survol + # disparaisse ensuite doit poser l'action inverse sur "Fin du survol" + # lui-même, plutôt que de compter sur un retour automatique. + ("survol", "Au survol"), + ("fin_survol", "Fin du survol"), # Pas de "trigger_element_id" pour celui-ci : il concerne l'ÉCRAN entier, # pas un élément précis (voir 1.2 dans claude/forge-engine-lacunes-boitemail.md # côté projet Forge — "affichage piloté par la donnée"). Se déclenche diff --git a/screens/labels/element_action_properties.py b/screens/labels/element_action_properties.py index 0a479aa3..84da90b2 100644 --- a/screens/labels/element_action_properties.py +++ b/screens/labels/element_action_properties.py @@ -2,6 +2,14 @@ ELEMENT_ACTION_PROPERTIES = [ ("visibilite", "Visibilité"), + # Voir TRIGGER_EVENTS ("survol"/"fin_survol") : c'est ce qui permet à un + # créateur de reconstruire l'ancien comportement "texte affiché au + # survol" (et bien d'autres) à la main dans la Logique de la scène — + # poser "Modifier un élément → Contenu" sur un déclencheur "Au survol" + # d'un AUTRE élément. La valeur est un texte littéral (pas encore de + # binding vers un champ d'objet ici — voir applyOpenRowBindings pour le + # mécanisme équivalent, propre à "Ouvrir la ligne cliquée"). + ("contenu", "Contenu — texte affiché"), ("bg_color", "Couleur de fond"), ("border_color", "Couleur de bordure"), ("width", "Largeur en %"), diff --git a/screens/labels/trigger_labels.py b/screens/labels/trigger_labels.py index c72a0e5d..49bc3531 100644 --- a/screens/labels/trigger_labels.py +++ b/screens/labels/trigger_labels.py @@ -2,4 +2,6 @@ TRIGGER_LABELS = { "clic": "Au clic", "soumission": "À la soumission", "affichage": "À l'affichage de l'écran", + "survol": "Au survol", + "fin_survol": "Fin du survol", } diff --git a/templates/play.html b/templates/play.html index 02c7ff76..1dc8e9c2 100644 --- a/templates/play.html +++ b/templates/play.html @@ -270,6 +270,26 @@ }); } + // Déclencheurs "Au survol" / "Fin du survol" — même principe que + // bindClicks() (garde-fou anti-doublon compris), mais sur mouseenter/ + // mouseleave plutôt que click, et les deux événements cherchés + // séparément puisque ce sont deux déclencheurs distincts et indépendants + // (voir le commentaire sur TRIGGER_EVENTS dans screens/flow/constants.py + // — pas de retour automatique à l'état d'avant survol, un créateur qui en + // veut un doit poser l'action inverse sur "Fin du survol" lui-même). + function bindHoverTriggers() { + document.querySelectorAll('[data-element-id]').forEach(elDiv => { + if (elDiv.dataset.hoverTriggerBound) return; + const elementId = parseInt(elDiv.dataset.elementId, 10); + const enterTrigger = findTriggerNode(elementId, 'survol'); + const leaveTrigger = findTriggerNode(elementId, 'fin_survol'); + if (!enterTrigger && !leaveTrigger) return; + elDiv.dataset.hoverTriggerBound = '1'; + if (enterTrigger) elDiv.addEventListener('mouseenter', () => runFlowFrom(enterTrigger.id)); + if (leaveTrigger) elDiv.addEventListener('mouseleave', () => runFlowFrom(leaveTrigger.id)); + }); + } + // Résout, sur l'écran couramment affiché, les placeholders "champ entre // doubles accolades" restés tels quels dans le HTML statique (hors // Répéteur, donc jamais résolus au moment du rendu serveur) avec les @@ -340,6 +360,7 @@ applyOpenRowBindings(); bindClicks(); bindHoverTexts(); + bindHoverTriggers(); // Réévalue aussi les nœuds "À l'affichage de l'écran" de l'écran où // l'on se trouve déjà : une donnée vient de changer (ex: un outil // qu'on vient de débloquer), donc l'affichage doit se mettre à jour @@ -358,6 +379,16 @@ }; function applyElementProperty(targetEl, property, value) { + if (property === 'contenu') { + // Voir ELEMENT_ACTION_PROPERTIES ("contenu") : texte littéral, pas de + // binding vers un champ d'objet ici (contrairement à + // applyOpenRowBindings, propre à "Ouvrir la ligne cliquée"). Comme + // pour les autres réglages ci-dessous, cible n'importe quel élément — + // pointer ceci vers un conteneur remplacerait tout son contenu + // imbriqué, à éviter. + targetEl.textContent = value == null ? '' : value; + return; + } if (property === 'surbrillance') { // 3.3 (Confort) — surbrillance générique dynamique : un liseré qui // clignote (voir la classe .forgeHighlight et son animation dans le @@ -603,6 +634,7 @@ // directement sur l'écran. bindClicks(); bindHoverTexts(); + bindHoverTriggers(); diff --git a/templates/screen_edit.html b/templates/screen_edit.html index 41d9558d..3b518adb 100644 --- a/templates/screen_edit.html +++ b/templates/screen_edit.html @@ -420,6 +420,7 @@ +