import json from flask import render_template, request, abort import db import screens from core.flask_app import app @app.route("/game//screens//edit") def screen_edit(slug, screen_id): game = db.game_meta(slug) screen = screens.get_screen(slug, screen_id) if not screen: abort(404) elements = screens.list_elements(slug, screen_id) all_screens = screens.list_screens(slug) element_types = screens.list_element_types(slug) selected_id = request.args.get("selected", type=int) selected_controls = None personnage_data = None if selected_id: selected_el = next((e for e in elements if e["id"] == selected_id), None) if selected_el: template_definition_id = None if screen.get("is_template"): owning_type = screens.get_element_type_by_template_screen(slug, screen_id) if owning_type: template_definition_id = owning_type.get("bound_definition_id") selected_controls = screens.controls_with_values(slug, selected_el, template_definition_id) if selected_el.get("widget") == "personnage": # Phase 8 — panneau de propriétés sur-mesure (custom_panel, # voir registry.py) : pas de controls génériques à afficher, # juste la source (Forge/personnalisée) et son contenu. personnage_data = screens.resolve_personnage_data(selected_el) children_of = {} for el in elements: if el.get("parent_id"): children_of.setdefault(el["parent_id"], []).append(el) top_level_elements = [el for el in elements if not el.get("parent_id")] elements_by_id = {el["id"]: el for el in elements} definitions = db.list_definitions(slug) definitions_data = {str(d["id"]): screens.data_definition_options(slug, d["id"]) for d in definitions} # Phase 4 — nodeLabel() (static/js/screen_edit/flow-editor.js) affiche # le nom de l'objet visé par un nœud "Ajouter une ligne" ; DEFINITIONS_DATA # (ci-dessus) ne porte que lignes/champs, jamais le nom lui-même. definitions_names = {d["id"]: d["name"] for d in definitions} # list_flow_blocks() rattache paresseusement les nœuds "orphelins" # (block_id NULL, jeux créés avant les blocs) à un "Bloc principal" — # DOIT tourner avant list_flow_nodes() ci-dessous, sinon flow_nodes # garderait en mémoire un block_id périmé (None) pour ces nœuds. flow_blocks = screens.list_flow_blocks(slug, screen_id) flow_nodes = screens.list_flow_nodes(slug, screen_id) flow_edges = screens.list_flow_edges(slug, screen_id) elements_labels = {el["id"]: screens.element_label(el, screens.WIDGETS) for el in elements} screens_map = {s["id"]: s["name"] for s in all_screens} # Phase 8 — sélecteur d'animation à miniatures (nœud de flow "Jouer une # animation" / clip de Timeline "sprite") : scopé aux SEULES animations # de l'élément personnage réellement ciblé, jamais un catalogue global. element_animations_map = { el["id"]: screens.resolve_personnage_animations(el) for el in elements if el.get("widget") == "personnage" } animation_clips = screens.list_animation_clips(slug, screen_id) global_variables = db.list_global_variables(slug) custom_events = db.list_custom_events(slug) custom_event_usages = screens.list_custom_event_usages(slug) custom_events_map = {e["id"]: {"name": e["name"]} for e in custom_events} blocks_view = screens.blocks_view(flow_blocks, flow_nodes, elements_labels) return render_template( "screen_edit.html", game=game, screen=screen, elements=elements, top_level_elements=top_level_elements, children_of=children_of, container_widgets=screens.CONTAINER_WIDGETS, elements_by_id=elements_by_id, all_screens=all_screens, element_types=element_types, widgets=screens.WIDGETS, trigger_labels=screens.TRIGGER_LABELS, action_type_labels=screens.ACTION_TYPE_LABELS, element_action_properties=screens.ELEMENT_ACTION_PROPERTIES, element_action_property_labels=screens.ELEMENT_ACTION_PROPERTY_LABELS, element_visibility_values=screens.ELEMENT_VISIBILITY_VALUES, element_visibility_labels=screens.ELEMENT_VISIBILITY_LABELS, element_surbrillance_values=screens.ELEMENT_SURBRILLANCE_VALUES, element_desactive_values=screens.ELEMENT_DESACTIVE_VALUES, element_orientation_values=screens.ELEMENT_ORIENTATION_VALUES, sprite_library=screens.SPRITE_LIBRARY, sprite_library_json=json.dumps(screens.SPRITE_LIBRARY), personnage_data=personnage_data, element_animations_map_json=json.dumps(element_animations_map), data_operations=screens.DATA_OPERATIONS, data_operation_labels=screens.DATA_OPERATION_LABELS, definitions=definitions, definitions_json=json.dumps(definitions_data), selected_id=selected_id, selected_controls=selected_controls, flow_nodes=flow_nodes, flow_edges=flow_edges, flow_nodes_json=json.dumps(flow_nodes), flow_edges_json=json.dumps(flow_edges), trigger_events=screens.TRIGGER_EVENTS, condition_operators=screens.CONDITION_OPERATORS, elements_labels_json=json.dumps(elements_labels), screens_map_json=json.dumps(screens_map), action_type_labels_json=json.dumps(screens.ACTION_TYPE_LABELS), element_action_property_labels_json=json.dumps(screens.ELEMENT_ACTION_PROPERTY_LABELS), element_visibility_labels_json=json.dumps(screens.ELEMENT_VISIBILITY_LABELS), element_surbrillance_labels_json=json.dumps(screens.ELEMENT_SURBRILLANCE_LABELS), element_desactive_labels_json=json.dumps(screens.ELEMENT_DESACTIVE_LABELS), element_orientation_labels_json=json.dumps(screens.ELEMENT_ORIENTATION_LABELS), data_operation_labels_json=json.dumps(screens.DATA_OPERATION_LABELS), condition_operator_labels_json=json.dumps(screens.CONDITION_OPERATOR_LABELS), trigger_labels_json=json.dumps(screens.TRIGGER_LABELS), animation_clips=animation_clips, animation_clips_json=json.dumps(animation_clips), animate_css_catalog=screens.ANIMATE_CSS_CATALOG, animate_css_labels_json=json.dumps(screens.ANIMATE_CSS_LABELS), fontawesome_icons=screens.FONTAWESOME_ICONS, global_variables=global_variables, custom_events=custom_events, custom_event_usages=custom_event_usages, custom_events_map_json=json.dumps(custom_events_map), blocks_view=blocks_view, flow_blocks_json=json.dumps(flow_blocks), definitions_names_json=json.dumps(definitions_names), )