Files
Forge-Engine/routes/elements/element_add.py
T
williamandClaude Sonnet 5 9e076f8cf9
Build and deploy / test-python (push) Successful in 1m26s
Build and deploy / test-js (push) Successful in 6s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Refonte : vrai widget "Personnage" visuel (remplace l'UI de la Phase 7)
L'utilisateur a testé la Phase 7 (sprites pilotés via un menu déroulant
+ zone de texte dans la logique de flow) et l'a rejetée à raison : ce
n'est pas comme ça qu'un moteur de jeu (Phaser, Unity) gère un
personnage. Cette refonte remplace tout le flux d'AUTEURING par un vrai
widget visuel — le moteur d'exécution de la Phase 7 (runSpriteAnimation,
activeSpriteAnimations, orientation, kind="sprite" de la Timeline) reste
inchangé.

Nouveau widget "personnage" (screens/widgets/registry.py) :
- Rendu serveur dédié (special_render, screens/rendering/render_personnage.py)
  qui affiche la pose "idle" dès le HTML généré — jamais une image
  cassée à configurer après coup.
- Toutes ses données (source Forge ou sprites propres au créateur, quel
  personnage/quelles animations) vivent dans une seule clé JSON
  _personnage_data (screens/rendering/personnage_data.py), sans aucune
  migration de schéma (même patron que c_clause_list).
- Nouvelle échappatoire "custom_panel", symétrique à "special_render" mais
  pour le panneau de propriétés : ce widget affiche une galerie/un import
  de sprites sur-mesure plutôt que les contrôles génériques.

Galerie visuelle de personnages Forge (VRAIES miniatures, pas un emoji) :
- Panneau gauche "🎭 Personnages" : pose un personnage déjà configuré,
  animé immédiatement.
- Panneau droit (propriétés) : change le personnage Forge de l'élément
  sélectionné, ou importe les animations d'un sprite personnalisé.
- static/js/screen_edit/personnage-preview.js : lance l'aperçu animé de
  CHAQUE personnage du canevas dès le chargement de la page et après
  toute sauvegarde — le cœur de la demande ("je dois voir ça bouger").

Sélecteur d'animation à miniatures (nœud de flow "Jouer une animation" et
clip de Timeline "sprite") : remplace le menu déroulant/la zone de texte
par une grille de vraies miniatures, scopée aux SEULES animations du
personnage réellement ciblé (ELEMENT_ANIMATIONS_MAP, résolu côté serveur
à partir des propriétés de cet élément précis) — jamais un catalogue
global. Le format stocké sur le nœud/le clip ({frames, fps, loop}) est
inchangé, seule l'UI d'édition change.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 20:26:39 +02:00

39 lines
2.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from flask import request, redirect, url_for
import screens
from core.flask_app import app
@app.route("/game/<slug>/screens/<int:screen_id>/elements/add", methods=["POST"])
def element_add(slug, screen_id):
widget = request.form.get("widget", "conteneur")
from_catalogue = widget == "__catalogue__"
element_type_id = request.form.get("element_type_id") or None if from_catalogue else None
if from_catalogue and not element_type_id:
return redirect(url_for("screen_edit", slug=slug, screen_id=screen_id))
if from_catalogue:
types = {t["id"]: t for t in screens.list_element_types(slug)}
et = types.get(int(element_type_id))
widget = et["default_widget"] if et else "conteneur"
new_id = screens.add_element(slug, screen_id, widget, element_type_id)
icon_slug = request.form.get("icon_class")
if widget == "icone" and icon_slug in screens.FONTAWESOME_ICONS:
# Posé depuis la galerie d'icônes (voir le panneau de propriétés,
# section "Icônes") : l'icône choisie remplace celle posée par
# défaut à la création plutôt que de repartir d'une icône neutre que
# l'utilisateur devrait ensuite changer manuellement.
screens.save_element_controls(slug, new_id, {"ctrl_icon_class": icon_slug})
if widget == "personnage":
# Posé depuis la galerie "🎭 Personnages" (voir addPersonnageElement()
# dans tree-panels.js) : remplace le personnage Forge par défaut
# (male-adventurer, voir default_style_for_widget.py) par celui
# réellement cliqué, ou bascule sur une source "custom" vide si la
# tuile "➕ Sprite personnalisé" a été choisie.
forge_character = request.form.get("forge_character")
if forge_character == "__custom__":
screens.set_personnage_data(slug, new_id, {"source": "custom", "animations": {}})
elif forge_character and forge_character in screens.SPRITE_LIBRARY:
screens.set_personnage_data(slug, new_id, {"source": "forge", "forge_character": forge_character})
return redirect(url_for("screen_edit", slug=slug, screen_id=screen_id, selected=new_id))