mirror of
https://forge.apps.education.fr/blender-edutech/jumeaux-numeriques.git
synced 2024-01-27 06:56:18 +01:00
651 lines
35 KiB
Python
651 lines
35 KiB
Python
import bge # Bibliothèque Blender Game Engine (UPBGE)
|
||
import bpy # Blender
|
||
import os
|
||
import importlib
|
||
import webbrowser
|
||
import time
|
||
|
||
###############################################################################
|
||
# twin_doc.py
|
||
# @title: Documentation de l'environnement 3D pour jumeau numérique
|
||
# @project: Blender-EduTech
|
||
# @lang: fr
|
||
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
|
||
# @copyright: Copyright (C) 2020-2023 Philippe Roy
|
||
# @license: GNU GPL
|
||
###############################################################################
|
||
|
||
# UPBGE scene
|
||
scene = bge.logic.getCurrentScene()
|
||
|
||
# Colors
|
||
color_doc_chap = (0.198, 0.109, 0.8, 1) # Violet
|
||
color_doc_fct = (0.198, 0.109, 0.8, 1) # Violet
|
||
color_doc_hl = (0.8, 0.005, 0.315, 1) # Magenta
|
||
# color_doc_activate = (0.936, 0.033, 1, 1) # Activé : Rose
|
||
color_doc_activate = (0.051, 0.270, 0.279,1) # Turquoise
|
||
# color_doc_activate = (0.936, 0.033, 1, 1) # Activé : Rose
|
||
|
||
# UPBGE constants
|
||
JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED
|
||
JUST_RELEASED = bge.logic.KX_INPUT_JUST_RELEASED
|
||
ACTIVATE = bge.logic.KX_INPUT_ACTIVE
|
||
# JUST_DEACTIVATED = bge.logic.KX_SENSOR_JUST_DEACTIVATED
|
||
|
||
# Cards description
|
||
card_description ={}
|
||
|
||
# Documentation du sytème
|
||
system=importlib.import_module(scene.objects['System']['system']+'_doc') # Système
|
||
system_card = system.get_system_card()
|
||
card_description.update(system.get_system_card_description())
|
||
|
||
###############################################################################
|
||
# Documentation Python
|
||
###############################################################################
|
||
|
||
# "oop-card"
|
||
python_card=["function-card", "alternative-card", "loop-card", "flow-card", "text-card", "list-card", "dict-card", "console-card", "sleep-card", "python-card"]
|
||
|
||
# Fonction
|
||
card_function_title="Fonction"
|
||
card_function_text=" La définition d'une fonction se fait avec \n \"def\". La fonction peut renvoyer une \n valeur avec \"return\". \n\n"
|
||
card_function_text=card_function_text + " def fonction_1 (arguments) : \n instruction_1 \n instruction_2 \n ....\n return valeurs_renvoyées \n\n"
|
||
card_function_text=card_function_text + " Les arguments sont des données \n transmises à la fonction."
|
||
card_function_url=[["w3schools.com : functions","https://www.w3schools.com/python/python_functions.asp"]]
|
||
card_description.update({"function-card" : [card_function_title, card_function_text, card_function_url]})
|
||
|
||
# Alternative
|
||
card_alternative_title="Alternative"
|
||
card_alternative_text=" L'alternative permet d'éxécuter des \n instructions en fonction d'un test. \n"
|
||
card_alternative_text=card_alternative_text + " Elle se programme en suivant la suite : \n \"if \" (si) ... \"else\" (sinon) ... \n\n"
|
||
card_alternative_text=card_alternative_text + " if condition :\n"
|
||
card_alternative_text=card_alternative_text + " instruction_1\n"
|
||
card_alternative_text=card_alternative_text + " else : \n"
|
||
card_alternative_text=card_alternative_text + " instruction_2\n\n"
|
||
card_alternative_text=card_alternative_text + "Le \"else\" (sinon) est facultatif."
|
||
card_alternative_url=[["w3schools.com : if ... else","https://www.w3schools.com/python/python_conditions.asp"]]
|
||
card_description.update({"alternative-card" : [card_alternative_title, card_alternative_text, card_alternative_url]})
|
||
|
||
# Boucles
|
||
card_loop_title="Boucles"
|
||
card_loop_text=" Il y a deux types de boucle : \n - avec \"for\" pour définir un nombre de \n répétition (ici n), \n - avec \"while\" (tant que) pour prendre \n en compte une condition. \n \n"
|
||
card_loop_text=card_loop_text + " for i in range (n) : \n instruction \n \n"
|
||
card_loop_text=card_loop_text + " while condition : \n instruction"
|
||
card_loop_url=[["w3schools.com : for","https://www.w3schools.com/python/python_for_loops.asp"],
|
||
["w3schools.com : while","https://www.w3schools.com/python/python_while_loops.asp"]]
|
||
card_description.update({"loop-card" : [card_loop_title, card_loop_text, card_loop_url]})
|
||
|
||
# Flux
|
||
card_flow_title="Contrôle du flux"
|
||
card_flow_text=""" Les structures (if, while, for) peuvent \n être gérées plus finement par les \n fonctions "break", "continue" et "pass". \n
|
||
- break : termine l'itération en cours et \n arrête la boucle.
|
||
- continue : termine l'itération en cours \n et reprend la boucle.
|
||
- pass : instruction vide."""
|
||
card_flow_url=[["w3schools.com : break","https://www.w3schools.com/python/ref_keyword_break.asp"],
|
||
["w3schools.com : continue","https://www.w3schools.com/python/ref_keyword_break.asp"],
|
||
["w3schools.com : pass","https://www.w3schools.com/python/ref_keyword_pass.asp"]]
|
||
card_description.update({"flow-card" : [card_flow_title, card_flow_text, card_flow_url]})
|
||
|
||
# Chaîne de caractères
|
||
card_text_title="Chaîne de caractères"
|
||
card_text_text=""" Une chaîne de caractères correspond à un \n texte (mot, phrase). Elle est délimitée \n par " ou ' : texte = "Bonjour !" \n
|
||
- texte1 + texte2 : concaténe plusieurs \n chaînes.
|
||
- len(texte) : renvoie la longueur de texte.
|
||
- "\\n" : caractère aller à la ligne.
|
||
- texte[i] : renvoie le caractère du rang i.
|
||
- texte[2:5] : renvoie les caractères du rang \n 2 au rang 5.
|
||
- texte.replace("a","b") : remplace les "a" \n par des "b". """
|
||
card_text_url=[
|
||
["Doc. Python v3 Français : string","https://docs.python.org/fr/3/library/string.html"],
|
||
["w3schools.com : strings","https://www.w3schools.com/python/python_strings.asp"]]
|
||
card_description.update({"text-card" : [card_text_title, card_text_text, card_text_url]})
|
||
|
||
# Liste
|
||
card_list_title="Liste"
|
||
card_list_text=""" Une liste est une séquence d'éléments. \n Elle est délimitée par des crochets :
|
||
liste = ["pomme", 7, "rouge", True] \n
|
||
- liste[i] : renvoie l'élément du rang i de la \n liste (commence à 0).
|
||
- liste.append("neige") : ajoute "neige" à la \n fin de la liste.
|
||
- len(liste) : renvoie le nombre d'éléments.
|
||
- liste.sort() : classe par ordre croissant la \n liste (alphabétiquement / numériquement).
|
||
- liste.remove("rouge") : enlève la première \n occurence de la valeur "rouge"."""
|
||
card_list_url=[
|
||
["Doc. Python v3 Français : list","https://docs.python.org/fr/3/library/stdtypes.html#sequence-types-list-tuple-range"],
|
||
["w3schools.com : lists","https://www.w3schools.com/python/python_lists.asp"]]
|
||
card_description.update({"list-card" : [card_list_title, card_list_text, card_list_url]})
|
||
|
||
# Dictionnaire
|
||
card_dict_title="Dictionnaire"
|
||
card_dict_text=""" Un dictionnaire est une collection \n d'éléments. Il est délimité par des \n accolades, chaque valeur est associée à
|
||
une clé unique : dct = {"nom": "Haddock",\n "prénom": "Archibald", "année": 1940} \n
|
||
- dct[clé] : renvoie la valeur liée à la clé.
|
||
- dct.update("domicile" : "Moulinsart") : \n met à jour les paires de clé/valeur.
|
||
- len(dct) : renvoie le nombre d'éléments.
|
||
- list(dct) : renvoie la liste des clés.
|
||
- dct.pop("année") : enlève la valeur \n associée à la clé (ici 1940)."""
|
||
card_dict_url=[
|
||
["Doc. Python v3 Français : dict","https://docs.python.org/fr/3/library/stdtypes.html#mapping-types-dict"],
|
||
["w3schools.com : dictionaries","https://www.w3schools.com/python/python_dictionaries.asp"]]
|
||
card_description.update({"dict-card" : [card_dict_title, card_dict_text, card_dict_url]})
|
||
|
||
# Objet (POO)
|
||
# card_oop_title="Programmation\norientée objet (POO)"
|
||
# card_oop_text="\nFIXME"
|
||
# card_oop_url=[["w3schools.com : classes & objects","https://www.w3schools.com/python/python_classes.asp"]]
|
||
# card_description.update({"oop-card" : [card_oop_title, card_oop_text, card_oop_url]})
|
||
|
||
# Console
|
||
card_console_title="Console"
|
||
card_console_text=" Si vous avez executé le simulateur dans \n un terminal (avec l'option \"-con\"), vous \n pouvez utiliser le terminal comme \n console de debuggage.\n\n"
|
||
card_console_text= card_console_text + " print(\"Bonjour !\") \n -> Affiche le texte dans la console.\n\n"
|
||
card_console_text= card_console_text + " variable = input () \n -> Permet la saisie, par exemple : \n"
|
||
card_console_text= card_console_text + " entree = \"\"\n while entree == \"\" :\n entree = input ()"
|
||
card_console_url=[["w3schools.com : print","https://www.w3schools.com/python/ref_func_print.asp"],
|
||
["w3schools.com : input","https://www.w3schools.com/python/ref_func_input.asp"]]
|
||
card_description.update({"console-card" : [card_console_title, card_console_text, card_console_url]})
|
||
|
||
# Temps
|
||
card_sleep_title="Gestion du temps"
|
||
card_sleep_text=""" tempo(x) \n -> Marque un temps d'arrêt de x secondes.
|
||
Vous pouvez alors créer des temporisations \n dans le déroulement du script.\n
|
||
get_t() \n -> Retourne le temps écoulé en seconde \n depuis le démarrage du cycle. \n
|
||
set_t(x) -> Définir la valeur (x) du temps. \n
|
||
reset_t() -> Réinitialiser la valeur du temps."""
|
||
card_sleep_url=[["Doc. Python v3 Fr : sleep","https://docs.python.org/fr/3/library/time.html#time.sleep"]]
|
||
card_description.update({"sleep-card" : [card_sleep_title, card_sleep_text, card_sleep_url]})
|
||
|
||
# Python
|
||
card_python_title="Langage Python"
|
||
card_python_text=""" Python est un langage de programmation \n interprété open source. Python vise à être
|
||
visuellement épuré avec une syntaxe \n clairement séparée des mécanismes de \n bas niveau.\n
|
||
Python possède beaucoup de bibliothèques \n spécialisées. Multiplateformes et
|
||
multiparadigme, il est utilisé dans de \n nombreux contextes : scriptage, calcul
|
||
numérique, prototypage, enseignement, \n ou encore comme langage de commande \n pour de nombreux logiciels."""
|
||
|
||
card_python_url=[["python.org","https://python.org"], ["AFPy","https://www.afpy.org"]]
|
||
card_description.update({"python-card" : [card_python_title, card_python_text, card_python_url]})
|
||
|
||
###############################################################################
|
||
# Interface
|
||
###############################################################################
|
||
|
||
##
|
||
# Initialisation de la documentation
|
||
##
|
||
|
||
def init():
|
||
|
||
# UI : information
|
||
scene.objects['Cmd-text']['Text']= "Chargement de la documentation ..."
|
||
scene.objects['Cmd-text'].setVisible(True,False)
|
||
|
||
# Mettre les couleurs sur les icones (chapitres et cartes)
|
||
chap=("general", "system", "python")
|
||
for page in chap:
|
||
scene.objects["Doc-"+page].color = color_doc_chap
|
||
scene.objects["Doc-"+page+"-text"].color = color_doc_chap
|
||
for i in range(len(system_card)):
|
||
scene.objects[system_card[i]].color = color_doc_fct
|
||
scene.objects[system_card[i]+"-icon"].color = color_doc_fct
|
||
scene.objects[system_card[i]+"-text"].color = color_doc_fct
|
||
for i in range(len(python_card)):
|
||
scene.objects[python_card[i]].color = color_doc_fct
|
||
scene.objects[python_card[i]+"-icon"].color = color_doc_fct
|
||
scene.objects[python_card[i]+"-text"].color = color_doc_fct
|
||
|
||
# Cacher et mettre les couleurs sur les liens (URL)
|
||
scene.objects['Doc_chap-system-url_title'].setVisible(False,True)
|
||
scene.objects['Doc_chap-system-url_title'].color = color_doc_activate
|
||
scene.objects['Doc_chap-python-url_title'].setVisible(False,True)
|
||
scene.objects['Doc_chap-python-url_title'].color = color_doc_activate
|
||
for i in range(3):
|
||
scene.objects['Doc_chap-python-url'+str(i)].setVisible(False,True)
|
||
scene.objects['Doc_chap-python-url'+str(i)+'-colbox'].suspendPhysics()
|
||
scene.objects['Doc_chap-python-url'+str(i)].color = color_doc_chap
|
||
scene.objects['Doc_chap-system-url'+str(i)].setVisible(False,True)
|
||
scene.objects['Doc_chap-system-url'+str(i)+'-colbox'].suspendPhysics()
|
||
scene.objects['Doc_chap-system-url'+str(i)].color = color_doc_chap
|
||
|
||
# Chargement du texte
|
||
if scene.objects['Doc']['static']: # en statique
|
||
text_static_load()
|
||
else:
|
||
text_dynamic_load() # en dynamique
|
||
|
||
# Mémorisation de la position des pages
|
||
for page in chap:
|
||
scene.objects["Doc_chap-"+page]['init_lx']=scene.objects["Doc_chap-"+page].worldPosition.x
|
||
scene.objects["Doc_chap-"+page]['init_ly']=scene.objects["Doc_chap-"+page].worldPosition.y
|
||
scene.objects["Doc_chap-"+page]['init_lz']=scene.objects["Doc_chap-"+page].worldPosition.z
|
||
|
||
# Page par défaut
|
||
scene.objects['Doc']['page_chap'] = "general"
|
||
|
||
# UI : information
|
||
# scene.objects['Cmd-text']['Text']= ""
|
||
# scene.objects['Cmd-text'].setVisible(False,False)
|
||
|
||
##
|
||
# Ouvrir la documentation
|
||
##
|
||
|
||
def open():
|
||
|
||
# Chargement de la documentation
|
||
if scene.objects['Doc']['page_chap']=="":
|
||
init()
|
||
|
||
# Placer la tablette
|
||
scene.objects['System']['manip_mode']=8 # Fenêtre modale Documentation
|
||
scene.objects['Doc-cmd-Hl'].setVisible(False,False)
|
||
scene.objects['Doc-cmd'].setVisible(True,False)
|
||
scene.objects['Cmd-text'].setVisible(False,False)
|
||
scene.objects['Twins-icon'].setVisible(False,True)
|
||
scene.objects['Twins-text'].setVisible(False,True)
|
||
scene.objects['Script-icon'].setVisible(False,True)
|
||
scene.objects['Script-text'].setVisible(False,True)
|
||
bpy.context.view_layer.update() # Bug de mise à jour
|
||
scene.active_camera = scene.objects["Camera-Doc"]
|
||
# scene.removeOverlayCollection(bpy.data.collections['Hud']) # Crash de UPBGE sur la supression de l'Overlay
|
||
# scene.objects['Twins-icon'].setVisible(False,True) # Crash de UPBGE sur la supression de l'Overlay
|
||
# scene.objects['Twins-text'].setVisible(False,True) # Crash de UPBGE sur la supression de l'Overlay
|
||
scene.objects['Doc_close'].color= color_doc_fct
|
||
scene.objects['Doc'].setVisible(True,True)
|
||
if scene.objects['Doc']['static']:
|
||
scene.objects['Doc_title'].setVisible(False,True)
|
||
for i in range (13):
|
||
scene.objects['Doc_text-l'+str(i+1)+'-ref'].setVisible(False, False)
|
||
else:
|
||
text_dynamic_hide()
|
||
|
||
# Placer le nouveau chapitre
|
||
name_chap = scene.objects['Doc']['page_chap']
|
||
scene.objects['Doc-'+name_chap].color = color_doc_activate
|
||
scene.objects['Doc-'+name_chap+'-text'].color = color_doc_activate
|
||
scene.objects['Doc_chap-'+name_chap].worldPosition = scene.objects['Doc'].worldPosition
|
||
scene.objects['Doc_chap-'+name_chap].setVisible(True,True)
|
||
|
||
# URL
|
||
if name_chap == "system" or name_chap == "python":
|
||
name_fct = scene.objects['Doc_chap-'+name_chap]['page_fct']
|
||
scene.objects['Doc_chap-'+name_chap+'-url_title'].setVisible(False,True)
|
||
for i in range(3):
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)].setVisible(False,True)
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox'].suspendPhysics()
|
||
if name_fct !="":
|
||
if len(card_description[name_fct][2])>0:
|
||
scene.objects['Doc_chap-'+name_chap+'-url_title'].setVisible(True,True)
|
||
for i in range(len(card_description[name_fct][2])):
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)]['Text'] = card_description[name_fct][2][i][0]
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)].setVisible(True,True)
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox'].restorePhysics()
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox']['Url'] = card_description[name_fct][2][i][1]
|
||
|
||
# Afficher le texte de la carte active
|
||
if scene.objects['Doc']['static'] :
|
||
pass
|
||
else:
|
||
if name_chap != "general" and scene.objects['Doc_chap-'+name_chap]['page_fct'] !="":
|
||
name_fct = scene.objects['Doc_chap-'+name_chap]['page_fct']
|
||
# scene.objects['Doc_title']['Text'] = card_description[name_fct][0]
|
||
scene.objects['Doc_title'].blenderObject.data.body=card_description[name_fct][0] # Bug de la propriétés 'Text' (UPBGE) -> passage par 'body' de bpy (Blender)
|
||
scene.objects['Doc_title'].setVisible(True, False)
|
||
text_dynamic_show(name_fct)
|
||
else:
|
||
# scene.objects['Doc_title']['Text'] = " "
|
||
scene.objects['Doc_title'].blenderObject.data.body=" " # Bug de la propriétés 'Text' (UPBGE) -> passage par 'body' de bpy (Blender)
|
||
scene.objects['Doc_title'].setVisible(False,True)
|
||
text_dynamic_hide()
|
||
|
||
##
|
||
# Fermer la documentation
|
||
##
|
||
|
||
def close(cont):
|
||
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive :
|
||
scene.objects['System']['manip_mode']=0 # Enlever la fenêtre modale
|
||
scene.active_camera = scene.objects["Camera"]
|
||
# scene.addOverlayCollection(scene.cameras['Camera-Hud'], bpy.data.collections['Hud']) # Crash de UPBGE sur la supression de l'Overlay
|
||
scene.objects['Twins-icon'].setVisible(True,True) # Crash de UPBGE sur la supression de l'Overlay
|
||
scene.objects['Twins-text'].setVisible(True,True) # Crash de UPBGE sur la supression de l'Overlay
|
||
scene.objects['Script-icon'].setVisible(True,True) # Crash de UPBGE sur la supression de l'Overlay
|
||
scene.objects['Script-text'].setVisible(True,True) # Crash de UPBGE sur la supression de l'Overlay
|
||
bpy.context.view_layer.update() # Bug de mise à jour
|
||
chap=("general", "system", "python")
|
||
for page in chap:
|
||
scene.objects["Doc_chap-"+page].setVisible(False,True)
|
||
scene.objects["Doc_chap-"+page].worldPosition.x = scene.objects["Doc_chap-"+page]['init_lx']
|
||
scene.objects["Doc_chap-"+page].worldPosition.y = scene.objects["Doc_chap-"+page]['init_ly']
|
||
scene.objects["Doc_chap-"+page].worldPosition.z = scene.objects["Doc_chap-"+page]['init_lz']
|
||
scene.objects['Doc'].setVisible(False,True)
|
||
if scene.objects['Doc']['static'] :
|
||
for card in card_description:
|
||
scene.objects["Doc_page-"+card].setVisible(False,True)
|
||
scene.objects["Doc_title-"+card].setVisible(False,True)
|
||
scene.objects["Doc_text-"+card].setVisible(False,True)
|
||
else:
|
||
text_dynamic_hide()
|
||
|
||
##
|
||
# Highlight
|
||
##
|
||
|
||
def hl (cont):
|
||
|
||
# Activation
|
||
if cont.sensors['MO'].status == JUST_ACTIVATED :
|
||
obj = cont.owner
|
||
name=obj.name[:-7]
|
||
name_text=name+"-text"
|
||
name_icon=name+"-icon"
|
||
|
||
# Close ou lien
|
||
if name == "Doc_close" :
|
||
scene.objects[name].color = color_doc_hl
|
||
elif name == "Doc_chap-python-url0" or name == "Doc_chap-python-url1" or name == "Doc_chap-python-url2":
|
||
scene.objects[name].color = color_doc_hl
|
||
elif name == "Doc_chap-system-url0" or name == "Doc_chap-system-url1" or name == "Doc_chap-system-url2":
|
||
scene.objects[name].color = color_doc_hl
|
||
else:
|
||
if "Doc-" in name : # Chapitre
|
||
if name[4:] == scene.objects['Doc']['page_chap']:
|
||
scene.objects[name].color = color_doc_activate
|
||
scene.objects[name_text].color = color_doc_activate
|
||
else:
|
||
scene.objects[name].color = color_doc_hl
|
||
scene.objects[name_text].color = color_doc_hl
|
||
else: # Carte
|
||
name_chap = scene.objects['Doc']['page_chap']
|
||
if name == scene.objects['Doc_chap-'+name_chap]['page_fct'] :
|
||
scene.objects[name].color = color_doc_activate
|
||
scene.objects[name_text].color = color_doc_activate
|
||
scene.objects[name_icon].color = color_doc_activate
|
||
else:
|
||
scene.objects[name].color = color_doc_hl
|
||
scene.objects[name_text].color = color_doc_hl
|
||
scene.objects[name_icon].color = color_doc_hl
|
||
|
||
# Désactivation
|
||
if cont.sensors['MO'].status == JUST_RELEASED :
|
||
obj = cont.owner
|
||
name=obj.name[:-7]
|
||
name_text=obj.name[:-7]+"-text"
|
||
name_icon=obj.name[:-7]+"-icon"
|
||
|
||
# Close ou lien
|
||
if name == "Doc_close" :
|
||
scene.objects[name].color = color_doc_fct
|
||
elif name == "Doc_chap-python-url0" or name == "Doc_chap-python-url1" or name == "Doc_chap-python-url2":
|
||
scene.objects[name].color = color_doc_fct
|
||
elif name == "Doc_chap-system-url0" or name == "Doc_chap-system-url1" or name == "Doc_chap-system-url2":
|
||
scene.objects[name].color = color_doc_fct
|
||
else:
|
||
if "Doc-" in name : # Chapitre
|
||
if name[4:] == scene.objects['Doc']['page_chap']:
|
||
scene.objects[name].color = color_doc_activate
|
||
scene.objects[name_text].color = color_doc_activate
|
||
else:
|
||
scene.objects[name].color = color_doc_fct
|
||
scene.objects[name_text].color = color_doc_fct
|
||
else: # Carte
|
||
name_chap = scene.objects['Doc']['page_chap']
|
||
if name == scene.objects['Doc_chap-'+name_chap]['page_fct'] :
|
||
scene.objects[name].color = color_doc_activate
|
||
scene.objects[name_text].color = color_doc_activate
|
||
scene.objects[name_icon].color = color_doc_activate
|
||
else:
|
||
scene.objects[name].color = color_doc_fct
|
||
scene.objects[name_text].color = color_doc_fct
|
||
scene.objects[name_icon].color = color_doc_fct
|
||
|
||
##
|
||
# Afficher le chapitre
|
||
##
|
||
|
||
def chapter(cont):
|
||
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive and cont.sensors['Click'].positive:
|
||
obj = cont.owner
|
||
# scene.objects['Doc_title']['Text'] = " "
|
||
scene.objects['Doc_title'].blenderObject.data.body=" " # Bug de la propriétés 'Text' (UPBGE) -> passage par 'body' de bpy (Blender)
|
||
|
||
# Enlever l'ancien chapitre
|
||
name_chap = scene.objects['Doc']['page_chap']
|
||
scene.objects['Doc-'+scene.objects['Doc']['page_chap']].color = color_doc_chap
|
||
scene.objects['Doc-'+scene.objects['Doc']['page_chap']+'-text'].color = color_doc_chap
|
||
scene.objects["Doc_chap-"+name_chap].worldPosition.x = scene.objects["Doc_chap-"+name_chap]['init_lx']
|
||
scene.objects["Doc_chap-"+name_chap].worldPosition.y = scene.objects["Doc_chap-"+name_chap]['init_ly']
|
||
scene.objects["Doc_chap-"+name_chap].worldPosition.z = scene.objects["Doc_chap-"+name_chap]['init_lz']
|
||
if scene.objects['Doc']['page_chap'] != "general" and scene.objects["Doc_chap-"+name_chap]['page_fct'] !="":
|
||
if scene.objects['Doc']['static'] :
|
||
name_chap = scene.objects['Doc']['page_chap']
|
||
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].worldPosition.x = scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']]['init_lx']
|
||
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].worldPosition.y = scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']]['init_ly']
|
||
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].worldPosition.z = scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']]['init_lz']
|
||
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].setVisible(False,True)
|
||
else:
|
||
text_dynamic_hide(scene.objects["Doc_chap-"+scene.objects['Doc']['page_chap']]['page_fct'])
|
||
|
||
# Placer le nouveau chapitre
|
||
name_chap= obj.name[4:-7]
|
||
scene.objects['Doc-'+name_chap].color = color_doc_activate
|
||
scene.objects['Doc-'+name_chap+'-text'].color = color_doc_activate
|
||
scene.objects['Doc']['page_chap'] = name_chap
|
||
scene.objects['Doc_chap-'+name_chap].worldPosition = scene.objects['Doc'].worldPosition
|
||
scene.objects['Doc_chap-'+name_chap].setVisible(True,True)
|
||
|
||
# URL
|
||
if name_chap == "system" or name_chap == "python":
|
||
name_fct = scene.objects['Doc_chap-'+name_chap]['page_fct']
|
||
scene.objects['Doc_chap-'+name_chap+'-url_title'].setVisible(False,True)
|
||
for i in range(3):
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)].setVisible(False,True)
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox'].suspendPhysics()
|
||
if name_fct !="":
|
||
if len(card_description[name_fct][2])>0:
|
||
scene.objects['Doc_chap-'+name_chap+'-url_title'].setVisible(True,True)
|
||
for i in range(len(card_description[name_fct][2])):
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)]['Text'] = card_description[name_fct][2][i][0]
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)].setVisible(True,True)
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox'].restorePhysics()
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox']['Url'] = card_description[name_fct][2][i][1]
|
||
|
||
# Afficher le texte de la carte active
|
||
if name_chap != "general" and scene.objects['Doc_chap-'+name_chap]['page_fct'] !="":
|
||
if scene.objects['Doc']['static'] :
|
||
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']]['init_lx']=scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].worldPosition.x
|
||
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']]['init_ly']=scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].worldPosition.y
|
||
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']]['init_lz']=scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].worldPosition.z
|
||
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].worldPosition = scene.objects['Doc'].worldPosition
|
||
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].setVisible(True,True)
|
||
else:
|
||
name_fct = scene.objects['Doc_chap-'+name_chap]['page_fct']
|
||
# scene.objects['Doc_title']['Text'] = card_description[name_fct][0]
|
||
scene.objects['Doc_title'].blenderObject.data.body=card_description[name_fct][0] # Bug de la propriétés 'Text' (UPBGE) -> passage par 'body' de bpy (Blender)
|
||
scene.objects['Doc_title'].setVisible(True, False)
|
||
text_dynamic_show(name_fct)
|
||
else:
|
||
if scene.objects['Doc']['static'] :
|
||
pass
|
||
else:
|
||
# scene.objects['Doc_title']['Text'] = " "
|
||
scene.objects['Doc_title'].blenderObject.data.body=" " # Bug de la propriétés 'Text' (UPBGE) -> passage par 'body' de bpy (Blender)
|
||
scene.objects['Doc_title'].setVisible(False,True)
|
||
text_dynamic_hide()
|
||
|
||
##
|
||
# Afficher les details de la fonction à partir d'une carte
|
||
##
|
||
|
||
def card (cont):
|
||
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive :
|
||
obj = cont.owner
|
||
name_chap = scene.objects['Doc']['page_chap']
|
||
name_fct= obj.name[:-7]
|
||
name_old_fct= scene.objects['Doc_chap-'+name_chap]['page_fct']
|
||
# scene.objects['Doc_title']['Text'] = " "
|
||
scene.objects['Doc_title'].blenderObject.data.body=" " # Bug de la propriétés 'Text' (UPBGE) -> passage par 'body' de bpy (Blender)
|
||
|
||
# Enlever l'ancienne carte
|
||
if name_old_fct !="":
|
||
if scene.objects['Doc']['static'] :
|
||
scene.objects["Doc_page-"+name_old_fct].worldPosition.x = scene.objects["Doc_page-"+name_old_fct]['init_lx']
|
||
scene.objects["Doc_page-"+name_old_fct].worldPosition.y = scene.objects["Doc_page-"+name_old_fct]['init_ly']
|
||
scene.objects["Doc_page-"+name_old_fct].worldPosition.z = scene.objects["Doc_page-"+name_old_fct]['init_lz']
|
||
scene.objects["Doc_page-"+name_old_fct].setVisible(False,True)
|
||
else:
|
||
text_dynamic_hide(name_old_fct)
|
||
scene.objects[name_old_fct].color = color_doc_fct
|
||
scene.objects[name_old_fct+'-text'].color = color_doc_fct
|
||
scene.objects[name_old_fct+'-icon'].color = color_doc_fct
|
||
|
||
# Afficher le texte de la carte
|
||
scene.objects['Doc_chap-'+name_chap]['page_fct'] = name_fct
|
||
scene.objects[name_fct].color = color_doc_activate
|
||
scene.objects[name_fct+'-icon'].color = color_doc_activate
|
||
scene.objects[name_fct+'-text'].color = color_doc_activate
|
||
if scene.objects['Doc']['static'] :
|
||
scene.objects["Doc_page-"+name_fct].worldPosition = scene.objects['Doc'].worldPosition
|
||
scene.objects["Doc_page-"+name_fct].setVisible(True,True)
|
||
else:
|
||
# scene.objects['Doc_title']['Text'] = card_description[name_fct][0]
|
||
scene.objects['Doc_title'].blenderObject.data.body=card_description[name_fct][0] # Bug de la propriétés 'Text' (UPBGE) -> passage par 'body' de bpy (Blender)
|
||
scene.objects['Doc_title'].setVisible(True, False)
|
||
text_dynamic_show(name_fct)
|
||
|
||
# URL
|
||
if name_chap == "system" or name_chap == "python":
|
||
name_fct = scene.objects['Doc_chap-'+name_chap]['page_fct']
|
||
scene.objects['Doc_chap-'+name_chap+'-url_title'].setVisible(False,True)
|
||
for i in range(3):
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)].setVisible(False,True)
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox'].suspendPhysics()
|
||
if name_fct !="":
|
||
if len(card_description[name_fct][2])>0:
|
||
scene.objects['Doc_chap-'+name_chap+'-url_title'].setVisible(True,True)
|
||
for i in range(len(card_description[name_fct][2])):
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)]['Text'] = card_description[name_fct][2][i][0]
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)].setVisible(True,True)
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox'].restorePhysics()
|
||
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox']['Url'] = card_description[name_fct][2][i][1]
|
||
|
||
##
|
||
# Aller à la page internet
|
||
##
|
||
|
||
def link (cont):
|
||
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive :
|
||
webbrowser.open(cont.owner['Url'])
|
||
|
||
|
||
###############################################################################
|
||
# Génération dynamique des pages
|
||
###############################################################################
|
||
|
||
##
|
||
# Cacher le texte
|
||
##
|
||
|
||
def text_dynamic_hide(card=None):
|
||
if card is None:
|
||
for card in card_description:
|
||
for i in range (13):
|
||
scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)].setVisible(False, False)
|
||
else:
|
||
for i in range (13):
|
||
scene.objects['Doc_text-l'+str(i+1)+'-'+card].setVisible(False, False)
|
||
|
||
##
|
||
# Afficher le texte
|
||
##
|
||
|
||
def text_dynamic_show(card=None):
|
||
if card is None:
|
||
for card in card_description:
|
||
for i in range (13):
|
||
scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)].setVisible(True, False)
|
||
else:
|
||
for i in range (13):
|
||
scene.objects['Doc_text-l'+str(i+1)+'-'+card].setVisible(True, False)
|
||
|
||
##
|
||
# Préchargement des textes
|
||
##
|
||
|
||
def text_dynamic_load():
|
||
for i in range (13):
|
||
scene.objects['Doc_text-l'+str(i+1)+'-ref']['Text'] = ""
|
||
|
||
# Création des objets 3D
|
||
for card in card_description:
|
||
if len(card_description[card][1][0])>1:
|
||
if scene.objects['System']['variant']-1 >len(card_description[card][1]):
|
||
lines = card_description[card][1][scene.objects['System']['variant']-1].split("\n") # Plusieurs versions de la description (fonction de la variante)
|
||
else:
|
||
lines = card_description[card][1][0].split("\n") # Si le nombre de description est inférieur au numéro de variante -> la description 1 est prise par défaut
|
||
else:
|
||
lines = card_description[card][1].split("\n")
|
||
for i in range (13):
|
||
doc_text= scene.addObject('Doc_text-l'+str(i+1), None, 0.00, True)
|
||
doc_text.setParent(scene.objects['Doc'])
|
||
doc_text.name = 'Doc_text-l'+str(i+1)+'-'+str(card)
|
||
doc_text.worldPosition.x = scene.objects['Doc_text-l'+str(i+1)+'-ref'].worldPosition.x
|
||
doc_text.worldPosition.y = scene.objects['Doc_text-l'+str(i+1)+'-ref'].worldPosition.y
|
||
doc_text.worldPosition.z = scene.objects['Doc_text-l'+str(i+1)+'-ref'].worldPosition.z
|
||
doc_text.setVisible(False, False)
|
||
if i >= len(lines):
|
||
scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)]['Text']=""
|
||
else:
|
||
if len(lines[i]) ==0:
|
||
scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)]['Text']=""
|
||
else:
|
||
# scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)]['Text']=lines[i]
|
||
scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)].blenderObject.data.body=lines[i] # Bug de la propriétés 'Text' (UPBGE) -> passage par 'body' de bpy (Blender)
|
||
|
||
###############################################################################
|
||
# Chargement des pages statiques
|
||
###############################################################################
|
||
|
||
def text_static_load():
|
||
|
||
# Charger la collection
|
||
file_path = "asset/doc/porcou_doc-fr.blend"
|
||
inner_path = "Collection"
|
||
object_name ="Doc generation"
|
||
bpy.ops.wm.append(
|
||
filepath=os.path.join(file_path, inner_path, object_name),
|
||
directory=os.path.join(file_path, inner_path),
|
||
filename=object_name)
|
||
scene.convertBlenderCollection(bpy.data.collections[object_name], True)
|
||
|
||
# Lier et configurer les objects
|
||
for card in card_description:
|
||
|
||
# Repère
|
||
page_name ="Doc_page-"+card
|
||
scene.objects[page_name]['init_lx']=scene.objects[page_name].worldPosition.x
|
||
scene.objects[page_name]['init_ly']=scene.objects[page_name].worldPosition.y
|
||
scene.objects[page_name]['init_lz']=scene.objects[page_name].worldPosition.z
|
||
|
||
# Titre
|
||
title_name ="Doc_title-"+card
|
||
scene.objects[title_name]. setParent(scene.objects[page_name], True, False)
|
||
bpy.data.objects[title_name].data.font=bpy.data.fonts['Espresso Dolce Regular']
|
||
scene.objects[title_name].worldPosition.x += scene.objects[page_name].worldPosition.x
|
||
scene.objects[title_name].worldPosition.y += scene.objects[page_name].worldPosition.y
|
||
scene.objects[title_name].worldPosition.z += scene.objects[page_name].worldPosition.z
|
||
|
||
# Texte
|
||
text_name ="Doc_text-"+card
|
||
scene.objects[text_name]. setParent(scene.objects[page_name], True, False)
|
||
# text_object=scene.objects[text_name].blenderObject.data
|
||
# text_object.font=bpy.data.fonts['Espresso Dolce Regular'] # Trop lourd
|
||
bpy.data.objects[text_name].data.font=bpy.data.fonts['Bfont Regular'] # Bien plus léger
|
||
scene.objects[text_name].worldPosition.x += scene.objects[page_name].worldPosition.x
|
||
scene.objects[text_name].worldPosition.y += scene.objects[page_name].worldPosition.y
|
||
scene.objects[text_name].worldPosition.z += scene.objects[page_name].worldPosition.z
|
||
|
||
scene.objects[page_name].setVisible(False,True)
|
||
scene.objects[title_name].setVisible(False,True)
|
||
scene.objects[text_name].setVisible(False,True)
|