- "ℹ️ Informations" (propriétés d'un personnage) : nom éditable, réutilisé comme "qui parle" dans l'éditeur de dialogue de quête (menu déroulant, plus "Joueur" toujours disponible) — remplace l'ancien choix binaire joueur/pnj. db.sanitize_quest_dialogues accepte maintenant un nom libre. - Nouveau menu "🖥️ Interface" (palette d'objets) avec le premier widget : "💬 Boîte de dialogue" (kind="dialogue_box", screens/rendering/ dialogue_box_style.py) — position/taille comme tout objet de scène, panneau "🎨 Style" dédié (police, taille, épaisseur, couleur du texte, couleur header/body/footer). Rendu en <div> à 3 zones, jamais soumis à la collision ni à l'éditeur de collision (exclu partout : obstacles, liste des règles, payload). Rendu côté jeu dans .sceneUI, une couche FIXE au viewport (jamais .sceneWorld, qui défile avec la caméra). - static/js/play/dialogue-box-controller.js : fait le lien moteur entre l'action "quete" de l'éditeur de collision et ce widget — affiche la réplique en cours du dialogue correspondant au STATUT ACTUEL de la quête (gameData.quests, désormais exposé game-wide par full_game_payload.py), avance au clic sur "Suivant" (header = qui parle, body = texte, footer = bouton), se masque à la dernière réplique. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
183 lines
10 KiB
Python
183 lines
10 KiB
Python
"""
|
|
screens.py — écrans de jeu : éléments posés en glisser-déposer sur un
|
|
écran, sans jamais toucher à un fichier HTML/CSS, enchaînement des écrans,
|
|
et actions déclenchées par clic ou soumission de formulaire.
|
|
|
|
Version 3 — inspirée d'Elementor / Bricks Builder : un catalogue fermé de
|
|
WIDGETS (Texte, Titre, Image, Bouton, Case à cocher, Répéteur de
|
|
données...), chacun avec ses propres réglages ("controls") : un réglage =
|
|
un champ, une case à cocher, un bouton radio ou un curseur — jamais de nom
|
|
de balise ni de nom de propriété CSS à taper. En coulisses, chaque widget
|
|
correspond à une vraie balise HTML avec de vrais attributs et un vrai
|
|
style CSS ; l'utilisateur ne les manipule jamais directement.
|
|
|
|
Tout est stocké dans la même base SQLite que le reste du jeu
|
|
(projects/<slug>/game.db) :
|
|
- _screens : un écran du jeu (accueil, formulaire, scène...)
|
|
- _element_types : le "catalogue" des éléments de jeu réutilisables
|
|
(Personnage, Outil, IA...) que l'utilisateur crée
|
|
- _screen_elements : chaque élément posé sur un écran (widget, position
|
|
et taille en POURCENTAGE de l'écran, contenu,
|
|
attributs et style — dérivés des réglages du
|
|
widget, jamais saisis en texte libre)
|
|
- _actions : ce qui se passe au clic / à la soumission d'un
|
|
élément (écran suivant, écran précédent, aller à
|
|
un écran précis, ne rien faire)
|
|
|
|
Un élément peut aussi être un "Répéteur de données" : au lieu d'un contenu
|
|
fixe, il est relié à un objet défini dans ce jeu (voir db.py) et affiche
|
|
automatiquement une ligne par donnée existante — par exemple, tous les
|
|
niveaux d'un parcours — à partir d'un modèle de texte avec des
|
|
{{nom_de_champ}}.
|
|
|
|
Ce fichier est désormais un package (voir les sous-dossiers) organisé
|
|
selon "un fichier = une fonction, un dossier = une responsabilité" ; ce
|
|
module se contente de ré-exporter l'intégralité de l'API publique
|
|
utilisée par app.py et les templates, afin que `import screens` continue
|
|
de fonctionner à l'identique.
|
|
"""
|
|
|
|
from .widgets.registry import WIDGETS
|
|
from .widgets.container_widgets import CONTAINER_WIDGETS
|
|
from .widgets.layout_capable_widgets import LAYOUT_CAPABLE_WIDGETS
|
|
from .widgets.fontawesome_icons import FONTAWESOME_ICONS
|
|
from .widgets.widget_meta import widget_meta
|
|
from .widgets.controls_with_values import controls_with_values
|
|
from .widgets.data_definition_options import data_definition_options
|
|
|
|
from .labels.trigger_labels import TRIGGER_LABELS
|
|
from .labels.action_type_labels import ACTION_TYPE_LABELS
|
|
from .labels.element_action_properties import (
|
|
ELEMENT_ACTION_PROPERTIES, ELEMENT_ACTION_PROPERTY_LABELS,
|
|
ELEMENT_SURBRILLANCE_VALUES, ELEMENT_SURBRILLANCE_LABELS,
|
|
ELEMENT_DESACTIVE_VALUES, ELEMENT_DESACTIVE_LABELS,
|
|
ELEMENT_ORIENTATION_VALUES, ELEMENT_ORIENTATION_LABELS,
|
|
)
|
|
from .labels.element_visibility import ELEMENT_VISIBILITY_VALUES, ELEMENT_VISIBILITY_LABELS
|
|
from .labels.data_operations import DATA_OPERATIONS, DATA_OPERATION_LABELS
|
|
from .labels.sprite_library import PUBLIC_SPRITE_LIBRARY
|
|
from .labels.animal_sprite_library import ADMIN_SPRITE_LIBRARY
|
|
|
|
# SPRITE_LIBRARY (fusionné) : utilisé par resolve_personnage_animations
|
|
# pour la résolution RUNTIME (jeu jouable, tous rôles confondus — voir le
|
|
# plan "Bibliothèque de sprites animaux CraftPix" : aucun filtrage par
|
|
# rôle au runtime, seulement à la galerie/l'écriture). Les routes qui
|
|
# alimentent la galerie de l'éditeur doivent utiliser PUBLIC_SPRITE_LIBRARY
|
|
# ou ADMIN_SPRITE_LIBRARY selon le rôle, jamais SPRITE_LIBRARY directement.
|
|
SPRITE_LIBRARY = {**PUBLIC_SPRITE_LIBRARY, **ADMIN_SPRITE_LIBRARY}
|
|
ADMIN_ONLY_CHARACTER_SLUGS = set(ADMIN_SPRITE_LIBRARY)
|
|
from .labels.sprite_gallery import sprite_gallery_families
|
|
from .labels.background_library import BACKGROUND_LIBRARY
|
|
# Un seul pack aujourd'hui, licence CraftPix — tout BACKGROUND_LIBRARY est
|
|
# admin-only (voir core/sprite_gate.py::forbid_admin_only_background),
|
|
# jamais de version "publique" comme pour les personnages Kenney.
|
|
ADMIN_ONLY_BACKGROUND_SLUGS = set(BACKGROUND_LIBRARY)
|
|
from .rendering.list_used_forge_characters import list_used_forge_characters
|
|
|
|
from .flow.constants import (
|
|
TRIGGER_EVENTS, CONDITION_OPERATORS, CONDITION_OPERATOR_LABELS, CLICKED_ROW_ID, LAST_INSERTED_ROW_ID,
|
|
)
|
|
|
|
from .rendering.render_element_html import render_element_html
|
|
from .rendering.trigger_for import _trigger_for
|
|
from .rendering.personnage_data import resolve_personnage_data, resolve_personnage_animations, resolve_personnage_idle_frame
|
|
from .rendering.personnage_role import resolve_personnage_role, PERSONNAGE_ROLES, PERSONNAGE_ROLE_LABELS, DEFAULT_PERSONNAGE_ROLE
|
|
from .rendering.collision_settings import resolve_collision_settings, DEFAULT_COLLISION_SETTINGS, COLLISION_SHAPES
|
|
from .rendering.collision_rules import (
|
|
resolve_collision_rules, sanitize_collision_rules,
|
|
ACTION_TYPES, TRIGGER_TYPES, DEFAULT_PERIMETRE_PX,
|
|
)
|
|
from .rendering.personnage_commands import resolve_personnage_commands, DEFAULT_PERSONNAGE_COMMANDS, sanitize_extra_commands
|
|
from .rendering.personnage_names import list_personnage_names
|
|
from .rendering.dialogue_box_style import resolve_dialogue_box_style, sanitize_dialogue_box_style, DEFAULT_DIALOGUE_BOX_STYLE, FONT_WEIGHT_CHOICES
|
|
|
|
from .screens_repo.ensure_schema import ensure_schema
|
|
from .screens_repo.list_screens import list_screens
|
|
from .screens_repo.get_screen import get_screen
|
|
from .screens_repo.create_screen import create_screen
|
|
from .screens_repo.rename_screen import rename_screen
|
|
from .screens_repo.delete_screen import delete_screen
|
|
from .screens_repo.move_screen import move_screen
|
|
from .screens_repo.screens_referencing import screens_referencing
|
|
from .screens_repo.set_screen_aspect import set_screen_aspect
|
|
from .screens_repo.set_screen_background_music import set_screen_background_music
|
|
|
|
from .elements.list_elements import list_elements
|
|
from .elements.get_element import get_element
|
|
from .elements.add_element import add_element
|
|
from .elements.add_tab import add_tab
|
|
from .elements.update_element_geometry import update_element_geometry
|
|
from .elements.reorder_element import reorder_element
|
|
from .elements.move_element_to_container import move_element_to_container
|
|
from .elements.save_element_controls import save_element_controls
|
|
from .elements.delete_element import delete_element
|
|
from .elements.flow_nodes_referencing_element import flow_nodes_referencing_element
|
|
from .elements.duplicate_element import duplicate_element
|
|
from .elements.rename_element import rename_element
|
|
from .elements.set_personnage_data import set_personnage_data
|
|
|
|
from .scenes.ensure_scene_schema import ensure_scene_schema
|
|
from .scenes.add_scene_object import add_scene_object
|
|
from .scenes.list_scene_objects import list_scene_objects
|
|
from .scenes.get_scene_object import get_scene_object
|
|
from .scenes.update_scene_object_geometry import update_scene_object_geometry
|
|
from .scenes.delete_scene_object import delete_scene_object
|
|
from .scenes.set_scene_object_personnage_data import set_scene_object_personnage_data
|
|
from .scenes.set_scene_object_commands import set_scene_object_commands
|
|
from .scenes.set_scene_object_role import set_scene_object_role
|
|
from .scenes.set_scene_object_collision import set_scene_object_collision
|
|
from .scenes.set_scene_object_collision_rules import set_scene_object_collision_rules
|
|
from .scenes.set_scene_object_name import set_scene_object_name
|
|
from .scenes.set_scene_object_dialogue_box_style import set_scene_object_dialogue_box_style
|
|
from .scenes.render_scene_object import render_scene_object
|
|
from .scenes.flow_palette import TRIGGER_EVENTS_2D, ACTION_TYPE_LABELS_2D, OBJECT_ACTION_PROPERTIES
|
|
from .elements.element_label import element_label
|
|
|
|
from .element_types.list_element_types import list_element_types
|
|
from .element_types.get_element_type_by_template_screen import get_element_type_by_template_screen
|
|
from .element_types.create_element_type import create_element_type
|
|
from .element_types.update_element_type import update_element_type
|
|
from .element_types.element_type_usage_count import element_type_usage_count
|
|
from .element_types.delete_element_type import delete_element_type
|
|
|
|
from .legacy_actions.list_actions import list_actions
|
|
from .legacy_actions.add_action import add_action
|
|
from .legacy_actions.get_action import get_action
|
|
from .legacy_actions.delete_action import delete_action
|
|
|
|
from .flow.ensure_flow_schema import ensure_flow_schema
|
|
from .flow.list_flow_nodes import list_flow_nodes
|
|
from .flow.list_flow_edges import list_flow_edges
|
|
from .flow.get_flow_node import get_flow_node
|
|
from .flow.add_flow_node import add_flow_node
|
|
from .flow.move_flow_node import move_flow_node
|
|
from .flow.delete_flow_node import delete_flow_node
|
|
from .flow.add_flow_edge import add_flow_edge
|
|
from .flow.delete_flow_edge import delete_flow_edge
|
|
|
|
from .flow.blocks.list_flow_blocks import list_flow_blocks
|
|
from .flow.blocks.get_flow_block import get_flow_block
|
|
from .flow.blocks.create_flow_block import create_flow_block
|
|
from .flow.blocks.update_flow_block import update_flow_block
|
|
from .flow.blocks.delete_flow_block import delete_flow_block
|
|
from .flow.blocks.blocks_view import blocks_view
|
|
|
|
from .data_actions.apply_data_action import apply_data_action
|
|
from .data_actions.apply_variable_action import apply_variable_action
|
|
from .data_actions.apply_score_action import apply_score_action
|
|
from .data_actions.apply_status_action import apply_status_action
|
|
from .data_actions.apply_add_row_action import apply_add_row_action
|
|
|
|
from .animations.ensure_animation_schema import ensure_animation_schema
|
|
from .animations.list_animation_clips import list_animation_clips
|
|
from .animations.get_animation_clip import get_animation_clip
|
|
from .animations.add_animation_clip import add_animation_clip
|
|
from .animations.update_animation_clip import update_animation_clip
|
|
from .animations.delete_animation_clip import delete_animation_clip
|
|
from .animations.animate_css_catalog import ANIMATE_CSS_CATALOG, ANIMATE_CSS_LABELS
|
|
|
|
from .custom_events.list_custom_event_usages import list_custom_event_usages
|
|
from .custom_events.delete_custom_event import delete_custom_event
|
|
|
|
from .payload.full_game_payload import full_game_payload
|