Ajoute la fonctionnalite quiz autonome/plein ecran a la boite a quiz
Introduit la double categorie de modeles (boite de dialogue / page de quiz plein ecran) avec plein ecran, minuteur, score integre et ecran de resultat pour les modeles page ; ajoute les modeles "Manga" (boite et page) et "Classique" (page), pilotables aussi par l'assistant IA Ruby. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
559331f9cf
commit
7db4803b93
@@ -2,6 +2,8 @@ import html as html_lib
|
||||
|
||||
from ..rendering.personnage_data import resolve_personnage_idle_frame
|
||||
from ..rendering.dialogue_box_style import resolve_dialogue_box_style
|
||||
from ..rendering.quiz_box_config import resolve_quiz_box_config
|
||||
from ..rendering.quiz_box_templates import render_quiz_box
|
||||
|
||||
|
||||
def render_scene_object(obj):
|
||||
@@ -72,31 +74,20 @@ def render_scene_object(obj):
|
||||
)
|
||||
if obj["kind"] == "quiz_box":
|
||||
# Widget "❓ Boîte à quiz" (voir "🖥️ Interface") — réutilise le
|
||||
# MÊME style que "💬 Boîte de dialogue" (resolve_dialogue_box_style/
|
||||
# set_scene_object_dialogue_box_style, une seule "🎨 Style" pour
|
||||
# les deux) : header = "Quête : <titre>" (comme demandé), corps =
|
||||
# la question ET ses choix de réponse ensemble (remplis EN JEU par
|
||||
# static/js/play/dialogue-box-controller.js, data-quiz-role sert de
|
||||
# sélecteur) — pas de pied (une question se résout au clic sur un
|
||||
# choix, pas de "Suivant"). Masqué par défaut au jeu, comme la
|
||||
# boîte de dialogue.
|
||||
# MÊME style couleur/police que "💬 Boîte de dialogue"
|
||||
# (resolve_dialogue_box_style/set_scene_object_dialogue_box_style,
|
||||
# une seule "🎨 Style" pour les deux, appliquée à TOUS les
|
||||
# modèles ci-dessous). Le rendu HTML lui-même dépend du modèle
|
||||
# choisi (plein écran/minuteur/modèle, voir
|
||||
# screens/rendering/quiz_box_config.py) — voir
|
||||
# screens/rendering/quiz_box_templates.py pour le détail de
|
||||
# chacun (thèmes complets HTML+CSS+JS, demande explicite) ; tous
|
||||
# respectent le même contrat de data-quiz-role, lu EN JEU par
|
||||
# static/js/play/dialogue-box-controller.js. "defaut" (Classique)
|
||||
# reste pixel-identique au rendu d'avant cette extension.
|
||||
style = resolve_dialogue_box_style(obj)
|
||||
box_style = (
|
||||
f"position:absolute; left:{obj['x']}px; top:{obj['y']}px; "
|
||||
f"width:{obj['width']}px; height:{obj['height']}px; z-index:{obj['z_index']}; "
|
||||
f"font-family:{html_lib.escape(style['font_family'])}; font-size:{style['font_size']}px; "
|
||||
f"font-weight:{style['font_weight']}; color:{html_lib.escape(style['text_color'])};"
|
||||
)
|
||||
return (
|
||||
f'<div class="quizBoxWidget" role="dialog" aria-live="polite" aria-atomic="true" data-object-id="{obj["id"]}" data-element-id="{obj["id"]}" style="{box_style}">'
|
||||
f'<div class="quizBoxHeader" data-quiz-role="header" style="background:{html_lib.escape(style["header_bg"])}">Quête : Titre de la quête</div>'
|
||||
f'<div class="quizBoxBody" data-quiz-role="body" style="background:{html_lib.escape(style["body_bg"])}">'
|
||||
f'<p class="quizBoxQuestionText" data-quiz-role="question">La question s\'affiche ici.</p>'
|
||||
f'<div class="quizBoxChoices" data-quiz-role="choices">'
|
||||
f'<button type="button" class="quizBoxChoiceBtn" disabled>Choix A</button>'
|
||||
f'<button type="button" class="quizBoxChoiceBtn" disabled>Choix B</button>'
|
||||
f'</div></div></div>'
|
||||
)
|
||||
config = resolve_quiz_box_config(obj)
|
||||
return render_quiz_box(obj, config, style)
|
||||
if obj["kind"] == "score_widget":
|
||||
# Widget "🏆 Score" (voir "🖥️ Interface") — toujours VISIBLE une
|
||||
# fois posé (pas de collision/déclencheur, contrairement aux deux
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import json
|
||||
|
||||
import db
|
||||
|
||||
from ..rendering.quiz_box_config import sanitize_quiz_box_config
|
||||
from .ensure_scene_schema import ensure_scene_schema
|
||||
|
||||
|
||||
def set_scene_object_quiz_config(slug, object_id, raw_config):
|
||||
ensure_scene_schema(slug)
|
||||
conn = db.connect(slug)
|
||||
row = conn.execute("SELECT attributes FROM _scene_objects WHERE id = ?", (object_id,)).fetchone()
|
||||
if not row:
|
||||
conn.close()
|
||||
return None
|
||||
attributes = json.loads(row["attributes"] or "{}")
|
||||
config = sanitize_quiz_box_config(raw_config)
|
||||
attributes["_quiz_box_config"] = json.dumps(config)
|
||||
conn.execute("UPDATE _scene_objects SET attributes = ? WHERE id = ?", (json.dumps(attributes), object_id))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return config
|
||||
Reference in New Issue
Block a user