You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-30 16:26:50 +00:00
Merge branch 'master' of https://github.com/okamstudio/godot
This commit is contained in:
BIN
tools/docdump/locales/es/LC_MESSAGES/makedocs.mo
Normal file
BIN
tools/docdump/locales/es/LC_MESSAGES/makedocs.mo
Normal file
Binary file not shown.
142
tools/docdump/locales/es/LC_MESSAGES/makedocs.po
Normal file
142
tools/docdump/locales/es/LC_MESSAGES/makedocs.po
Normal file
@@ -0,0 +1,142 @@
|
||||
# Translations template for PROJECT.
|
||||
# Copyright (C) 2015 ORGANIZATION
|
||||
# This file is distributed under the same license as the PROJECT project.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: makedocs\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2015-10-07 11:47-0600\n"
|
||||
"PO-Revision-Date: 2015-10-07 13:10-0600\n"
|
||||
"Last-Translator: Jorge Araya Navarro <elcorreo@deshackra.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.0\n"
|
||||
"X-Generator: Poedit 1.8.4\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: makedocs.py:74
|
||||
msgid ""
|
||||
"\"<code>{gclass}</code>(Go to page of class {gclass})\":/class_{lkclass}"
|
||||
msgstr ""
|
||||
"\"<code>{gclass}</code>(Ir a la pagina de la clase {gclass})\":/"
|
||||
"class_{lkclass}"
|
||||
|
||||
#: makedocs.py:76
|
||||
msgid ""
|
||||
"\"<code>{gclass}.{method}</code>(Go to page {gclass}, section {method})\":/"
|
||||
"class_{lkclass}#{lkmethod}"
|
||||
msgstr ""
|
||||
"\"<code>{gclass}.{method}</code>(Ir a la pagina {gclass}, sección "
|
||||
"{method})\":/class_{lkclass}#{lkmethod}"
|
||||
|
||||
#: makedocs.py:79
|
||||
msgid "\"<code>{method}</code>(Jump to method {method})\":#{lkmethod}"
|
||||
msgstr "\"<code>{method}</code>(Saltar al método {method})\":#{lkmethod}"
|
||||
|
||||
#: makedocs.py:81
|
||||
msgid " \"{rtype}(Go to page of class {rtype})\":/class_{link} "
|
||||
msgstr " \"{rtype}(Ir a la pagina de la clase {rtype})\":/class_{link} "
|
||||
|
||||
#: makedocs.py:82
|
||||
msgid ""
|
||||
"\"*{funcname}*(Jump to description for node {funcname})\":#{link} <b>(</b> "
|
||||
msgstr ""
|
||||
"\"*{funcname}*(Saltar a la descripción para el nodo {funcname})\":#{link} "
|
||||
"<b>(</b> "
|
||||
|
||||
#: makedocs.py:87
|
||||
msgid "h4. Inherits: "
|
||||
msgstr "h4. Hereda de: "
|
||||
|
||||
#: makedocs.py:232
|
||||
msgid "<doc>'s version attribute missing"
|
||||
msgstr "El atributo version de <doc> no existe"
|
||||
|
||||
#: makedocs.py:246
|
||||
msgid "|_. Index symbol |_. Class name |_. Index symbol |_. Class name |\n"
|
||||
msgstr ""
|
||||
"|_. Índice de símbolo |_. Nombre de la clase |_. Índice de símbolo |_. "
|
||||
"Nombre de la clase |\n"
|
||||
|
||||
#: makedocs.py:305
|
||||
msgid ""
|
||||
"h4. Category: {}\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"h4. Categoría: {}\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:310
|
||||
msgid ""
|
||||
"h2. Brief Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"h2. Descripción breve\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:312
|
||||
msgid ""
|
||||
"\"read more\":#more\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\"Leer más\":#more\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:317
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Member Functions\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"h3. Funciones miembro\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:323
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Signals\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"h3. Señales\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:331
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Numeric Constants\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"h3. Constantes numéricas\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:347
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3(#more). Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"h3(#more). Descripción\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:351
|
||||
msgid "_Nothing here, yet..._\n"
|
||||
msgstr "_Aún nada por aquí..._\n"
|
||||
|
||||
#: makedocs.py:355
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Member Function Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"h3. Descripción de las funciones miembro\n"
|
||||
"\n"
|
||||
108
tools/docdump/makedocs.pot
Normal file
108
tools/docdump/makedocs.pot
Normal file
@@ -0,0 +1,108 @@
|
||||
# Translations template for PROJECT.
|
||||
# Copyright (C) 2015 ORGANIZATION
|
||||
# This file is distributed under the same license as the PROJECT project.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: makedocs 0.1\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2015-10-07 11:47-0600\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.0\n"
|
||||
"X-Generator: Poedit 1.8.4\n"
|
||||
|
||||
#: makedocs.py:74
|
||||
msgid "\"<code>{gclass}</code>(Go to page of class {gclass})\":/class_{lkclass}"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:76
|
||||
msgid "\"<code>{gclass}.{method}</code>(Go to page {gclass}, section {method})\":/class_{lkclass}#{lkmethod}"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:79
|
||||
msgid "\"<code>{method}</code>(Jump to method {method})\":#{lkmethod}"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:81
|
||||
msgid " \"{rtype}(Go to page of class {rtype})\":/class_{link} "
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:82
|
||||
msgid "\"*{funcname}*(Jump to description for node {funcname})\":#{link} <b>(</b> "
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:87
|
||||
msgid "h4. Inherits: "
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:232
|
||||
msgid "<doc>'s version attribute missing"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:246
|
||||
msgid "|_. Index symbol |_. Class name |_. Index symbol |_. Class name |\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:305
|
||||
msgid ""
|
||||
"h4. Category: {}\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:310
|
||||
msgid ""
|
||||
"h2. Brief Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:312
|
||||
msgid ""
|
||||
"\"read more\":#more\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:317
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Member Functions\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:323
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Signals\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:331
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Numeric Constants\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:347
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3(#more). Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:351
|
||||
msgid "_Nothing here, yet..._\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:355
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Member Function Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
382
tools/docdump/makedocs.py
Normal file
382
tools/docdump/makedocs.py
Normal file
@@ -0,0 +1,382 @@
|
||||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# makedocs.py: Generate documentation for Open Project Wiki
|
||||
# Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur.
|
||||
# Contributor: Jorge Araya Navarro <elcorreo@deshackra.com>
|
||||
#
|
||||
|
||||
# IMPORTANT NOTICE:
|
||||
# If you are going to modify anything from this file, please be sure to follow
|
||||
# the Style Guide for Python Code or often called "PEP8". To do this
|
||||
# automagically just install autopep8:
|
||||
#
|
||||
# $ sudo pip3 install autopep8
|
||||
#
|
||||
# and run:
|
||||
#
|
||||
# $ autopep8 makedocs.py
|
||||
#
|
||||
# Before committing your changes. Also be sure to delete any trailing
|
||||
# whitespace you may left.
|
||||
#
|
||||
# TODO:
|
||||
# * Refactor code.
|
||||
# * Adapt this script for generating content in other markup formats like
|
||||
# DokuWiki, Markdown, etc.
|
||||
#
|
||||
# Also check other TODO entries in this script for more information on what is
|
||||
# left to do.
|
||||
import argparse
|
||||
import gettext
|
||||
import logging
|
||||
import re
|
||||
from itertools import zip_longest
|
||||
from os import path, listdir
|
||||
from xml.etree import ElementTree
|
||||
|
||||
|
||||
# add an option to change the verbosity
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
|
||||
def getxmlfloc():
|
||||
""" Returns the supposed location of the XML file
|
||||
"""
|
||||
filepath = path.dirname(path.abspath(__file__))
|
||||
return path.join(filepath, "class_list.xml")
|
||||
|
||||
|
||||
def langavailable():
|
||||
""" Return a list of languages available for translation
|
||||
"""
|
||||
filepath = path.join(
|
||||
path.dirname(path.abspath(__file__)), "locales")
|
||||
files = listdir(filepath)
|
||||
choices = [x for x in files]
|
||||
choices.insert(0, "none")
|
||||
return choices
|
||||
|
||||
|
||||
desc = "Generates documentation from a XML file to different markup languages"
|
||||
|
||||
parser = argparse.ArgumentParser(description=desc)
|
||||
parser.add_argument("--input", dest="xmlfp", default=getxmlfloc(),
|
||||
help="Input XML file, default: {}".format(getxmlfloc()))
|
||||
parser.add_argument("--output-dir", dest="outputdir", required=True,
|
||||
help="Output directory for generated files")
|
||||
parser.add_argument("--language", choices=langavailable(), default="none",
|
||||
help=("Choose the language of translation"
|
||||
" for the output files. Default is English (none). "
|
||||
"Note: This is NOT for the documentation itself!"))
|
||||
# TODO: add an option for outputting different markup formats
|
||||
|
||||
args = parser.parse_args()
|
||||
# Let's check if the file and output directory exists
|
||||
if not path.isfile(args.xmlfp):
|
||||
logging.critical("File not found: {}".format(args.xmlfp))
|
||||
exit(1)
|
||||
elif not path.isdir(args.outputdir):
|
||||
logging.critical("Path does not exist: {}".format(args.outputdir))
|
||||
exit(1)
|
||||
|
||||
_ = gettext.gettext
|
||||
if args.language != "none":
|
||||
lang = gettext.translation(domain="makedocs",
|
||||
localedir="locales",
|
||||
languages=[args.language])
|
||||
lang.install()
|
||||
|
||||
_ = lang.gettext
|
||||
|
||||
# Strings
|
||||
C_LINK = _("\"<code>{gclass}</code>(Go to page of class"
|
||||
" {gclass})\":/class_{lkclass}")
|
||||
MC_LINK = _("\"<code>{gclass}.{method}</code>(Go "
|
||||
"to page {gclass}, section {method})\""
|
||||
":/class_{lkclass}#{lkmethod}")
|
||||
TM_JUMP = _("\"<code>{method}</code>(Jump to method"
|
||||
" {method})\":#{lkmethod}")
|
||||
GTC_LINK = _(" \"{rtype}(Go to page of class {rtype})\":/class_{link} ")
|
||||
DFN_JUMP = _("\"*{funcname}*(Jump to description for"
|
||||
" node {funcname})\":#{link} <b>(</b> ")
|
||||
M_ARG_DEFAULT = C_LINK + " {name}={default}"
|
||||
M_ARG = C_LINK + " {name}"
|
||||
|
||||
OPENPROJ_INH = _("h4. Inherits: ") + C_LINK + "\n\n"
|
||||
|
||||
|
||||
def tb(string):
|
||||
""" Return a byte representation of a string
|
||||
"""
|
||||
return bytes(string, "UTF-8")
|
||||
|
||||
|
||||
def sortkey(c):
|
||||
""" Symbols are first, letters second
|
||||
"""
|
||||
if "_" == c.attrib["name"][0]:
|
||||
return "A"
|
||||
else:
|
||||
return c.attrib["name"]
|
||||
|
||||
|
||||
def toOP(text):
|
||||
""" Convert commands in text to Open Project commands
|
||||
"""
|
||||
# TODO: Make this capture content between [command] ... [/command]
|
||||
groups = re.finditer((r'\[html (?P<command>/?\w+/?)(\]| |=)?(\]| |=)?(?P<a'
|
||||
'rg>\w+)?(\]| |=)?(?P<value>"[^"]+")?/?\]'), text)
|
||||
alignstr = ""
|
||||
for group in groups:
|
||||
gd = group.groupdict()
|
||||
if gd["command"] == "br/":
|
||||
text = text.replace(group.group(0), "\n\n", 1)
|
||||
elif gd["command"] == "div":
|
||||
if gd["value"] == '"center"':
|
||||
alignstr = ("{display:block; margin-left:auto;"
|
||||
" margin-right:auto;}")
|
||||
elif gd["value"] == '"left"':
|
||||
alignstr = "<"
|
||||
elif gd["value"] == '"right"':
|
||||
alignstr = ">"
|
||||
text = text.replace(group.group(0), "\n\n", 1)
|
||||
elif gd["command"] == "/div":
|
||||
alignstr = ""
|
||||
text = text.replace(group.group(0), "\n\n", 1)
|
||||
elif gd["command"] == "img":
|
||||
text = text.replace(group.group(0), "!{align}{src}!".format(
|
||||
align=alignstr, src=gd["value"].strip('"')), 1)
|
||||
elif gd["command"] == "b" or gd["command"] == "/b":
|
||||
text = text.replace(group.group(0), "*", 1)
|
||||
elif gd["command"] == "i" or gd["command"] == "/i":
|
||||
text = text.replace(group.group(0), "_", 1)
|
||||
elif gd["command"] == "u" or gd["command"] == "/u":
|
||||
text = text.replace(group.group(0), "+", 1)
|
||||
# Process other non-html commands
|
||||
groups = re.finditer((r'\[method ((?P<class>[aA0-zZ9_]+)(?:\.))'
|
||||
r'?(?P<method>[aA0-zZ9_]+)\]'), text)
|
||||
for group in groups:
|
||||
gd = group.groupdict()
|
||||
if gd["class"]:
|
||||
replacewith = (MC_LINK.format(gclass=gd["class"],
|
||||
method=gd["method"],
|
||||
lkclass=gd["class"].lower(),
|
||||
lkmethod=gd["method"].lower()))
|
||||
else:
|
||||
# The method is located in the same wiki page
|
||||
replacewith = (TM_JUMP.format(method=gd["method"],
|
||||
lkmethod=gd["method"].lower()))
|
||||
|
||||
text = text.replace(group.group(0), replacewith, 1)
|
||||
# Finally, [Classes] are around brackets, make them direct links
|
||||
groups = re.finditer(r'\[(?P<class>[az0-AZ0_]+)\]', text)
|
||||
for group in groups:
|
||||
gd = group.groupdict()
|
||||
replacewith = (C_LINK.
|
||||
format(gclass=gd["class"],
|
||||
lkclass=gd["class"].lower()))
|
||||
text = text.replace(group.group(0), replacewith, 1)
|
||||
|
||||
return text + "\n\n"
|
||||
|
||||
|
||||
def mkfn(node, is_signal=False):
|
||||
""" Return a string containing a unsorted item for a function
|
||||
"""
|
||||
finalstr = ""
|
||||
name = node.attrib["name"]
|
||||
rtype = node.find("return")
|
||||
if rtype:
|
||||
rtype = rtype.attrib["type"]
|
||||
else:
|
||||
rtype = "void"
|
||||
# write the return type and the function name first
|
||||
finalstr += "* "
|
||||
# return type
|
||||
if not is_signal:
|
||||
if rtype != "void":
|
||||
finalstr += GTC_LINK.format(
|
||||
rtype=rtype,
|
||||
link=rtype.lower())
|
||||
else:
|
||||
finalstr += " void "
|
||||
|
||||
# function name
|
||||
if not is_signal:
|
||||
finalstr += DFN_JUMP.format(
|
||||
funcname=name,
|
||||
link=name.lower())
|
||||
else:
|
||||
# Signals have no description
|
||||
finalstr += "*{funcname}* <b>(</b>".format(funcname=name)
|
||||
# loop for the arguments of the function, if any
|
||||
args = []
|
||||
for arg in sorted(
|
||||
node.iter(tag="argument"),
|
||||
key=lambda a: int(a.attrib["index"])):
|
||||
|
||||
ntype = arg.attrib["type"]
|
||||
nname = arg.attrib["name"]
|
||||
|
||||
if "default" in arg.attrib:
|
||||
args.insert(-1, M_ARG_DEFAULT.format(
|
||||
gclass=ntype,
|
||||
lkclass=ntype.lower(),
|
||||
name=nname,
|
||||
default=arg.attrib["default"]))
|
||||
else:
|
||||
# No default value present
|
||||
args.insert(-1, M_ARG.format(gclass=ntype,
|
||||
lkclass=ntype.lower(), name=nname))
|
||||
# join the arguments together
|
||||
finalstr += ", ".join(args)
|
||||
# and, close the function with a )
|
||||
finalstr += " <b>)</b>"
|
||||
# write the qualifier, if any
|
||||
if "qualifiers" in node.attrib:
|
||||
qualifier = node.attrib["qualifiers"]
|
||||
finalstr += " " + qualifier
|
||||
|
||||
finalstr += "\n"
|
||||
|
||||
return finalstr
|
||||
|
||||
# Let's begin
|
||||
tree = ElementTree.parse(args.xmlfp)
|
||||
root = tree.getroot()
|
||||
|
||||
# Check version attribute exists in <doc>
|
||||
if "version" not in root.attrib:
|
||||
logging.critical(_("<doc>'s version attribute missing"))
|
||||
exit(1)
|
||||
|
||||
version = root.attrib["version"]
|
||||
classes = sorted(root, key=sortkey)
|
||||
# first column is always longer, second column of classes should be shorter
|
||||
zclasses = zip_longest(classes[:int(len(classes) / 2 + 1)],
|
||||
classes[int(len(classes) / 2 + 1):],
|
||||
fillvalue="")
|
||||
|
||||
# We write the class_list file and also each class file at once
|
||||
with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl:
|
||||
# Write header of table
|
||||
fcl.write(tb("|^.\n"))
|
||||
fcl.write(tb(_("|_. Index symbol |_. Class name "
|
||||
"|_. Index symbol |_. Class name |\n")))
|
||||
fcl.write(tb("|-.\n"))
|
||||
|
||||
indexletterl = ""
|
||||
indexletterr = ""
|
||||
for gdclassl, gdclassr in zclasses:
|
||||
# write a row #
|
||||
# write the index symbol column, left
|
||||
if indexletterl != gdclassl.attrib["name"][0]:
|
||||
indexletterl = gdclassl.attrib["name"][0]
|
||||
fcl.write(tb("| *{}* |".format(indexletterl.upper())))
|
||||
else:
|
||||
# empty cell
|
||||
fcl.write(tb("| |"))
|
||||
# write the class name column, left
|
||||
fcl.write(tb(C_LINK.format(
|
||||
gclass=gdclassl.attrib["name"],
|
||||
lkclass=gdclassl.attrib["name"].lower())))
|
||||
|
||||
# write the index symbol column, right
|
||||
if isinstance(gdclassr, ElementTree.Element):
|
||||
if indexletterr != gdclassr.attrib["name"][0]:
|
||||
indexletterr = gdclassr.attrib["name"][0]
|
||||
fcl.write(tb("| *{}* |".format(indexletterr.upper())))
|
||||
else:
|
||||
# empty cell
|
||||
fcl.write(tb("| |"))
|
||||
# We are dealing with an empty string
|
||||
else:
|
||||
# two empty cell
|
||||
fcl.write(tb("| | |\n"))
|
||||
# We won't get the name of the class since there is no ElementTree
|
||||
# object for the right side of the tuple, so we iterate the next
|
||||
# tuple instead
|
||||
continue
|
||||
|
||||
# write the class name column (if any), right
|
||||
fcl.write(tb(C_LINK.format(
|
||||
gclass=gdclassl.attrib["name"],
|
||||
lkclass=gdclassl.attrib["name"].lower()) + "|\n"))
|
||||
|
||||
# row written #
|
||||
# now, let's write each class page for each class
|
||||
for gdclass in [gdclassl, gdclassr]:
|
||||
if not isinstance(gdclass, ElementTree.Element):
|
||||
continue
|
||||
|
||||
classname = gdclass.attrib["name"]
|
||||
with open(path.join(args.outputdir, "{}.txt".format(
|
||||
classname.lower())), "wb") as clsf:
|
||||
# First level header with the name of the class
|
||||
clsf.write(tb("h1. {}\n\n".format(classname)))
|
||||
# lay the attributes
|
||||
if "inherits" in gdclass.attrib:
|
||||
inh = gdclass.attrib["inherits"].strip()
|
||||
clsf.write(tb(OPENPROJ_INH.format(gclass=inh,
|
||||
lkclass=inh.lower())))
|
||||
if "category" in gdclass.attrib:
|
||||
clsf.write(tb(_("h4. Category: {}\n\n").
|
||||
format(gdclass.attrib["category"].strip())))
|
||||
# lay child nodes
|
||||
briefd = gdclass.find("brief_description")
|
||||
if briefd.text.strip():
|
||||
clsf.write(tb(_("h2. Brief Description\n\n")))
|
||||
clsf.write(tb(toOP(briefd.text.strip()) +
|
||||
_("\"read more\":#more\n\n")))
|
||||
|
||||
# Write the list of member functions of this class
|
||||
methods = gdclass.find("methods")
|
||||
if methods and len(methods) > 0:
|
||||
clsf.write(tb(_("\nh3. Member Functions\n\n")))
|
||||
for method in methods.iter(tag='method'):
|
||||
clsf.write(tb(mkfn(method)))
|
||||
|
||||
signals = gdclass.find("signals")
|
||||
if signals and len(signals) > 0:
|
||||
clsf.write(tb(_("\nh3. Signals\n\n")))
|
||||
for signal in signals.iter(tag='signal'):
|
||||
clsf.write(tb(mkfn(signal, True)))
|
||||
# TODO: <members> tag is necessary to process? it does not
|
||||
# exists in class_list.xml file.
|
||||
|
||||
consts = gdclass.find("constants")
|
||||
if consts and len(consts) > 0:
|
||||
clsf.write(tb(_("\nh3. Numeric Constants\n\n")))
|
||||
for const in sorted(consts, key=lambda k:
|
||||
k.attrib["name"]):
|
||||
if const.text.strip():
|
||||
clsf.write(tb("* *{name}* = *{value}* - {desc}\n".
|
||||
format(
|
||||
name=const.attrib["name"],
|
||||
value=const.attrib["value"],
|
||||
desc=const.text.strip())))
|
||||
else:
|
||||
# Constant have no description
|
||||
clsf.write(tb("* *{name}* = *{value}*\n".
|
||||
format(
|
||||
name=const.attrib["name"],
|
||||
value=const.attrib["value"])))
|
||||
descrip = gdclass.find("description")
|
||||
clsf.write(tb(_("\nh3(#more). Description\n\n")))
|
||||
if descrip.text:
|
||||
clsf.write(tb(descrip.text.strip() + "\n"))
|
||||
else:
|
||||
clsf.write(tb(_("_Nothing here, yet..._\n")))
|
||||
|
||||
# and finally, the description for each method
|
||||
if methods and len(methods) > 0:
|
||||
clsf.write(tb(_("\nh3. Member Function Description\n\n")))
|
||||
for method in methods.iter(tag='method'):
|
||||
clsf.write(tb("h4(#{n}). {name}\n\n".format(
|
||||
n=method.attrib["name"].lower(),
|
||||
name=method.attrib["name"])))
|
||||
clsf.write(tb(mkfn(method) + "\n"))
|
||||
clsf.write(tb(toOP(method.find(
|
||||
"description").text.strip())))
|
||||
@@ -547,6 +547,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
||||
class_desc->pop();
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
|
||||
}
|
||||
|
||||
@@ -563,6 +564,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
||||
_add_text(cd.brief_description);
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
}
|
||||
|
||||
bool method_descr=false;
|
||||
@@ -637,7 +639,6 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
||||
|
||||
if (cd.properties.size()) {
|
||||
|
||||
|
||||
class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/keyword_color"));
|
||||
class_desc->push_font(doc_title_font);
|
||||
class_desc->add_text("Members:");
|
||||
@@ -715,9 +716,10 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
||||
class_desc->add_newline();
|
||||
}
|
||||
|
||||
class_desc->add_newline();
|
||||
class_desc->pop();
|
||||
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
|
||||
}
|
||||
if (cd.signals.size()) {
|
||||
@@ -779,6 +781,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
||||
|
||||
class_desc->pop();
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
|
||||
}
|
||||
|
||||
@@ -823,6 +826,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
||||
|
||||
class_desc->pop();
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
|
||||
|
||||
}
|
||||
@@ -830,17 +834,18 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
||||
if (cd.description!="") {
|
||||
|
||||
description_line=class_desc->get_line_count()-2;
|
||||
|
||||
class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/keyword_color"));
|
||||
class_desc->push_font(doc_title_font);
|
||||
class_desc->add_text("Description:");
|
||||
class_desc->pop();
|
||||
class_desc->pop();
|
||||
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
_add_text(cd.description);
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
}
|
||||
|
||||
if (method_descr) {
|
||||
@@ -853,12 +858,16 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
||||
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
class_desc->push_indent(1);
|
||||
|
||||
|
||||
for(int i=0;i<cd.methods.size();i++) {
|
||||
|
||||
method_line[cd.methods[i].name]=class_desc->get_line_count()-2;
|
||||
|
||||
if( cd.methods[i].description != "") {
|
||||
class_desc->add_newline();
|
||||
}
|
||||
class_desc->push_font(doc_code_font);
|
||||
_add_type(cd.methods[i].return_type);
|
||||
|
||||
@@ -899,9 +908,12 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
||||
|
||||
class_desc->pop();
|
||||
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
_add_text(cd.methods[i].description);
|
||||
if( cd.methods[i].description != "") {
|
||||
class_desc->add_text(" ");
|
||||
_add_text(cd.methods[i].description);
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
}
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
|
||||
@@ -1392,6 +1404,8 @@ EditorHelp::EditorHelp(EditorNode *p_editor) {
|
||||
PanelContainer *pc = memnew( PanelContainer );
|
||||
Ref<StyleBoxFlat> style( memnew( StyleBoxFlat ) );
|
||||
style->set_bg_color( EditorSettings::get_singleton()->get("text_editor/background_color") );
|
||||
style->set_default_margin(MARGIN_LEFT,20);
|
||||
style->set_default_margin(MARGIN_TOP,20);
|
||||
pc->add_style_override("panel", style); //get_stylebox("normal","TextEdit"));
|
||||
h_split->add_child(pc);
|
||||
class_desc = memnew( RichTextLabel );
|
||||
|
||||
@@ -1108,6 +1108,11 @@ void EditorNode::_dialog_action(String p_file) {
|
||||
|
||||
push_item(res.operator->() );
|
||||
} break;
|
||||
case FILE_NEW_INHERITED_SCENE: {
|
||||
|
||||
|
||||
load_scene(p_file,false,true);
|
||||
} break;
|
||||
case FILE_OPEN_SCENE: {
|
||||
|
||||
|
||||
@@ -1931,6 +1936,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
||||
|
||||
|
||||
} break;
|
||||
case FILE_NEW_INHERITED_SCENE:
|
||||
case FILE_OPEN_SCENE: {
|
||||
|
||||
|
||||
@@ -1951,7 +1957,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
||||
if (scene) {
|
||||
file->set_current_path(scene->get_filename());
|
||||
};
|
||||
file->set_title("Open Scene");
|
||||
file->set_title(p_option==FILE_OPEN_SCENE?"Open Scene":"Open Base Scene");
|
||||
file->popup_centered_ratio();
|
||||
|
||||
} break;
|
||||
@@ -3312,7 +3318,7 @@ void EditorNode::fix_dependencies(const String& p_for_file) {
|
||||
dependency_fixer->edit(p_for_file);
|
||||
}
|
||||
|
||||
Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps) {
|
||||
Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps,bool p_set_inherited) {
|
||||
|
||||
if (!is_inside_tree()) {
|
||||
defer_load_scene = p_scene;
|
||||
@@ -3442,6 +3448,13 @@ Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps) {
|
||||
}
|
||||
*/
|
||||
|
||||
if (p_set_inherited) {
|
||||
Ref<SceneState> state = sdata->get_state();
|
||||
state->set_path(lpath);
|
||||
new_scene->set_scene_inherited_state(state);
|
||||
}
|
||||
|
||||
|
||||
set_edited_scene(new_scene);
|
||||
_get_scene_metadata();
|
||||
/*
|
||||
@@ -4404,6 +4417,7 @@ void EditorNode::_scene_tab_changed(int p_tab) {
|
||||
EditorNode::EditorNode() {
|
||||
|
||||
EditorHelp::generate_doc(); //before any editor classes are crated
|
||||
SceneState::set_disable_placeholders(true);
|
||||
|
||||
InputDefault *id = Input::get_singleton()->cast_to<InputDefault>();
|
||||
|
||||
@@ -4794,6 +4808,7 @@ EditorNode::EditorNode() {
|
||||
file_menu->set_tooltip("Operations with scene files.");
|
||||
p=file_menu->get_popup();
|
||||
p->add_item("New Scene",FILE_NEW_SCENE);
|
||||
p->add_item("New Inherited Scene..",FILE_NEW_INHERITED_SCENE);
|
||||
p->add_item("Open Scene..",FILE_OPEN_SCENE,KEY_MASK_CMD+KEY_O);
|
||||
p->add_separator();
|
||||
p->add_item("Save Scene",FILE_SAVE_SCENE,KEY_MASK_CMD+KEY_S);
|
||||
|
||||
@@ -107,6 +107,7 @@ class EditorNode : public Node {
|
||||
enum MenuOptions {
|
||||
|
||||
FILE_NEW_SCENE,
|
||||
FILE_NEW_INHERITED_SCENE,
|
||||
FILE_OPEN_SCENE,
|
||||
FILE_SAVE_SCENE,
|
||||
FILE_SAVE_AS_SCENE,
|
||||
@@ -565,7 +566,7 @@ public:
|
||||
|
||||
void fix_dependencies(const String& p_for_file);
|
||||
void clear_scene() { _cleanup_scene(); }
|
||||
Error load_scene(const String& p_scene,bool p_ignore_broken_deps=false);
|
||||
Error load_scene(const String& p_scene, bool p_ignore_broken_deps=false, bool p_set_inherited=false);
|
||||
Error load_resource(const String& p_scene);
|
||||
|
||||
bool is_scene_open(const String& p_path);
|
||||
|
||||
@@ -74,6 +74,7 @@ void EditorPlugin::add_custom_control(CustomControlContainer p_location,Control
|
||||
case CONTAINER_CANVAS_EDITOR_SIDE: {
|
||||
|
||||
CanvasItemEditor::get_singleton()->get_palette_split()->add_child(p_control);
|
||||
CanvasItemEditor::get_singleton()->get_palette_split()->move_child(p_control,0);
|
||||
|
||||
} break;
|
||||
case CONTAINER_CANVAS_EDITOR_BOTTOM: {
|
||||
|
||||
@@ -710,7 +710,7 @@ void EditorSampleImportPlugin::_compress_ima_adpcm(const Vector<float>& p_data,D
|
||||
*(out++) =0;
|
||||
|
||||
for (i=0;i<datalen;i++) {
|
||||
int step,diff,vpdiff,signed_nibble,p,mask;
|
||||
int step,diff,vpdiff,mask;
|
||||
uint8_t nibble;
|
||||
int16_t xm_sample;
|
||||
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
#include "multi_node_edit.h"
|
||||
#include "array_property_edit.h"
|
||||
#include "editor_help.h"
|
||||
#include "scene/resources/packed_scene.h"
|
||||
|
||||
|
||||
void CustomPropertyEditor::_notification(int p_what) {
|
||||
|
||||
@@ -1655,25 +1657,101 @@ CustomPropertyEditor::CustomPropertyEditor() {
|
||||
menu->connect("item_pressed",this,"_menu_option");
|
||||
}
|
||||
|
||||
bool PropertyEditor::_might_be_in_instance() {
|
||||
|
||||
|
||||
Node *PropertyEditor::get_instanced_node() {
|
||||
|
||||
//this sucks badly
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
Node *node = obj->cast_to<Node>();
|
||||
|
||||
Node* edited_scene =EditorNode::get_singleton()->get_edited_scene();
|
||||
|
||||
bool might_be=false;
|
||||
|
||||
while(node) {
|
||||
|
||||
if (node->get_scene_instance_state().is_valid()) {
|
||||
might_be=true;
|
||||
break;
|
||||
}
|
||||
if (node==edited_scene) {
|
||||
if (node->get_scene_inherited_state().is_valid()) {
|
||||
might_be=true;
|
||||
break;
|
||||
}
|
||||
might_be=false;
|
||||
break;
|
||||
}
|
||||
node=node->get_owner();
|
||||
}
|
||||
|
||||
return might_be;
|
||||
|
||||
}
|
||||
|
||||
bool PropertyEditor::_get_instanced_node_original_property(const StringName& p_prop,Variant& value) {
|
||||
|
||||
Node *node = obj->cast_to<Node>();
|
||||
|
||||
if (!node)
|
||||
return NULL;
|
||||
return false;
|
||||
|
||||
if (node->get_filename()=="")
|
||||
return NULL;
|
||||
Node *orig=node;
|
||||
|
||||
if (!node->get_owner())
|
||||
return NULL; //scene root i guess
|
||||
Node* edited_scene =EditorNode::get_singleton()->get_edited_scene();
|
||||
|
||||
return node;
|
||||
bool found=false;
|
||||
|
||||
// print_line("for prop - "+String(p_prop));
|
||||
|
||||
while(node) {
|
||||
|
||||
Ref<SceneState> ss;
|
||||
|
||||
if (node==edited_scene) {
|
||||
ss=node->get_scene_inherited_state();
|
||||
} else {
|
||||
ss=node->get_scene_instance_state();
|
||||
}
|
||||
// print_line("at - "+String(edited_scene->get_path_to(node)));
|
||||
|
||||
if (ss.is_valid()) {
|
||||
NodePath np = node->get_path_to(orig);
|
||||
int node_idx = ss->find_node_by_path(np);
|
||||
// print_line("\t valid, nodeidx "+itos(node_idx));
|
||||
if (node_idx>=0) {
|
||||
bool lfound=false;
|
||||
Variant lvar;
|
||||
lvar=ss->get_property_value(node_idx,p_prop,lfound);
|
||||
if (lfound) {
|
||||
found=true;
|
||||
value=lvar;
|
||||
// print_line("\t found value "+String(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node==edited_scene) {
|
||||
//just in case
|
||||
break;
|
||||
}
|
||||
node=node->get_owner();
|
||||
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
bool PropertyEditor::_is_property_different(const Variant& p_current, const Variant& p_orig,int p_usage) {
|
||||
|
||||
if (p_orig.get_type()==Variant::NIL) {
|
||||
//special cases
|
||||
if (p_current.is_zero() && p_usage&PROPERTY_USAGE_STORE_IF_NONZERO)
|
||||
return false;
|
||||
if (p_current.is_one() && p_usage&PROPERTY_USAGE_STORE_IF_NONONE)
|
||||
return false;
|
||||
}
|
||||
|
||||
return bool(Variant::evaluate(Variant::OP_NOT_EQUAL,p_current,p_orig));
|
||||
}
|
||||
|
||||
TreeItem *PropertyEditor::find_item(TreeItem *p_item,const String& p_name) {
|
||||
@@ -1910,6 +1988,8 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PropertyEditor::_notification(int p_what) {
|
||||
|
||||
if (p_what==NOTIFICATION_ENTER_TREE) {
|
||||
@@ -1950,12 +2030,16 @@ void PropertyEditor::_notification(int p_what) {
|
||||
if (!item)
|
||||
continue;
|
||||
|
||||
if (get_instanced_node()) {
|
||||
if (_might_be_in_instance()) {
|
||||
|
||||
Dictionary d = get_instanced_node()->get_instance_state();
|
||||
if (d.has(*k)) {
|
||||
|
||||
Variant vorig;
|
||||
Dictionary d=item->get_metadata(0);
|
||||
int usage = d.has("usage")?int(int(d["usage"])&(PROPERTY_USAGE_STORE_IF_NONONE|PROPERTY_USAGE_STORE_IF_NONZERO)):0;
|
||||
|
||||
|
||||
if (_get_instanced_node_original_property(*k,vorig) || usage) {
|
||||
Variant v = obj->get(*k);
|
||||
Variant vorig = d[*k];
|
||||
|
||||
int found=-1;
|
||||
for(int i=0;i<item->get_button_count(1);i++) {
|
||||
@@ -1966,7 +2050,7 @@ void PropertyEditor::_notification(int p_what) {
|
||||
}
|
||||
}
|
||||
|
||||
bool changed = ! (v==vorig);
|
||||
bool changed = _is_property_different(v,vorig,usage);
|
||||
|
||||
if ((found!=-1)!=changed) {
|
||||
|
||||
@@ -2049,12 +2133,14 @@ void PropertyEditor::_refresh_item(TreeItem *p_item) {
|
||||
|
||||
if (name!=String()) {
|
||||
|
||||
if (get_instanced_node()) {
|
||||
if (_might_be_in_instance()) {
|
||||
|
||||
Dictionary d = get_instanced_node()->get_instance_state();
|
||||
if (d.has(name)) {
|
||||
Variant vorig;
|
||||
Dictionary d=p_item->get_metadata(0);
|
||||
int usage = d.has("usage")?int(int(d["usage"])&(PROPERTY_USAGE_STORE_IF_NONONE|PROPERTY_USAGE_STORE_IF_NONZERO)):0;
|
||||
|
||||
if (_get_instanced_node_original_property(name,vorig) || usage) {
|
||||
Variant v = obj->get(name);
|
||||
Variant vorig = d[name];
|
||||
|
||||
int found=-1;
|
||||
for(int i=0;i<p_item->get_button_count(1);i++) {
|
||||
@@ -2065,7 +2151,7 @@ void PropertyEditor::_refresh_item(TreeItem *p_item) {
|
||||
}
|
||||
}
|
||||
|
||||
bool changed = ! (v==vorig);
|
||||
bool changed = _is_property_different(v,vorig,usage);
|
||||
|
||||
if ((found!=-1)!=changed) {
|
||||
|
||||
@@ -2326,7 +2412,8 @@ void PropertyEditor::update_tree() {
|
||||
d["type"]=(int)p.type;
|
||||
d["hint"]=(int)p.hint;
|
||||
d["hint_text"]=p.hint_string;
|
||||
|
||||
d["usage"]=(int)p.usage;
|
||||
|
||||
item->set_metadata( 0, d );
|
||||
item->set_metadata( 1, p.name );
|
||||
|
||||
@@ -2777,14 +2864,17 @@ void PropertyEditor::update_tree() {
|
||||
}
|
||||
}
|
||||
|
||||
if (get_instanced_node()) {
|
||||
if (_might_be_in_instance()) {
|
||||
|
||||
Dictionary d = get_instanced_node()->get_instance_state();
|
||||
if (d.has(p.name)) {
|
||||
Variant vorig;
|
||||
Dictionary d=item->get_metadata(0);
|
||||
int usage = d.has("usage")?int(int(d["usage"])&(PROPERTY_USAGE_STORE_IF_NONONE|PROPERTY_USAGE_STORE_IF_NONZERO)):0;
|
||||
if (_get_instanced_node_original_property(p.name,vorig) || usage) {
|
||||
Variant v = obj->get(p.name);
|
||||
Variant vorig = d[p.name];
|
||||
if (! (v==vorig)) {
|
||||
|
||||
|
||||
if (_is_property_different(v,vorig,usage)) {
|
||||
//print_line("FOR "+String(p.name)+" RELOAD WITH: "+String(v)+"("+Variant::get_type_name(v.get_type())+")=="+String(vorig)+"("+Variant::get_type_name(vorig.get_type())+")");
|
||||
item->add_button(1,get_icon("Reload","EditorIcons"),3);
|
||||
}
|
||||
}
|
||||
@@ -3081,17 +3171,18 @@ void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) {
|
||||
call_deferred("_set_range_def",ti,prop,ti->get_range(p_column)+1.0);
|
||||
} else if (p_button==3) {
|
||||
|
||||
if (!get_instanced_node())
|
||||
if (!_might_be_in_instance())
|
||||
return;
|
||||
if (!d.has("name"))
|
||||
return;
|
||||
|
||||
String prop=d["name"];
|
||||
|
||||
Dictionary d2 = get_instanced_node()->get_instance_state();
|
||||
if (d2.has(prop)) {
|
||||
Variant vorig;
|
||||
|
||||
_edit_set(prop,d2[prop]);
|
||||
if (_get_instanced_node_original_property(prop,vorig)) {
|
||||
|
||||
_edit_set(prop,vorig);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
@@ -121,6 +121,7 @@ class CustomPropertyEditor : public Popup {
|
||||
void show_value_editors(int p_amount);
|
||||
void config_value_editors(int p_amount, int p_columns,int p_label_w,const List<String>& p_strings);
|
||||
void config_action_buttons(const List<String>& p_strings);
|
||||
|
||||
protected:
|
||||
|
||||
void _notification(int p_what);
|
||||
@@ -184,13 +185,17 @@ class PropertyEditor : public Control {
|
||||
virtual void _changed_callback(Object *p_changed,const char * p_what);
|
||||
virtual void _changed_callbacks(Object *p_changed,const String& p_callback);
|
||||
|
||||
|
||||
void _edit_button(Object *p_item, int p_column, int p_button);
|
||||
|
||||
void _node_removed(Node *p_node);
|
||||
void _edit_set(const String& p_name, const Variant& p_value);
|
||||
void _draw_flags(Object *ti,const Rect2& p_rect);
|
||||
|
||||
Node *get_instanced_node();
|
||||
bool _might_be_in_instance();
|
||||
bool _get_instanced_node_original_property(const StringName& p_prop,Variant& value);
|
||||
bool _is_property_different(const Variant& p_current, const Variant& p_orig,int p_usage=0);
|
||||
|
||||
void _refresh_item(TreeItem *p_item);
|
||||
void _set_range_def(Object *p_item, String prop, float p_frame);
|
||||
|
||||
|
||||
@@ -103,6 +103,7 @@ ReparentDialog::ReparentDialog() {
|
||||
add_child(node_only);
|
||||
node_only->hide();
|
||||
|
||||
tree->set_show_enabled_subscene(true);
|
||||
//vbc->add_margin_child("Options:",node_only);;
|
||||
|
||||
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
#include "script_editor_debugger.h"
|
||||
#include "tools/editor/plugins/script_editor_plugin.h"
|
||||
#include "multi_node_edit.h"
|
||||
void SceneTreeDock::_unhandled_key_input(InputEvent p_event) {
|
||||
|
||||
void SceneTreeDock::_unhandled_key_input(InputEvent p_event) {
|
||||
|
||||
uint32_t sc = p_event.key.get_scancode_with_modifiers();
|
||||
if (!p_event.key.pressed || p_event.key.echo)
|
||||
@@ -71,7 +71,7 @@ Node* SceneTreeDock::instance(const String& p_file) {
|
||||
Node*instanced_scene=NULL;
|
||||
Ref<PackedScene> sdata = ResourceLoader::load(p_file);
|
||||
if (sdata.is_valid())
|
||||
instanced_scene=sdata->instance();
|
||||
instanced_scene=sdata->instance(true);
|
||||
|
||||
|
||||
if (!instanced_scene) {
|
||||
@@ -96,7 +96,7 @@ Node* SceneTreeDock::instance(const String& p_file) {
|
||||
}
|
||||
}
|
||||
|
||||
instanced_scene->generate_instance_state();
|
||||
//instanced_scene->generate_instance_state();
|
||||
instanced_scene->set_filename( Globals::get_singleton()->localize_path(p_file) );
|
||||
|
||||
editor_data->get_undo_redo().create_action("Instance Scene");
|
||||
@@ -158,8 +158,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
||||
case TOOL_NEW: {
|
||||
|
||||
|
||||
if (!_validate_no_foreign())
|
||||
break;
|
||||
//if (!_validate_no_foreign())
|
||||
// break;
|
||||
create_dialog->popup_centered_ratio();
|
||||
} break;
|
||||
case TOOL_INSTANCE: {
|
||||
@@ -176,8 +176,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!_validate_no_foreign())
|
||||
break;
|
||||
//if (!_validate_no_foreign())
|
||||
// break;
|
||||
|
||||
file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
|
||||
List<String> extensions;
|
||||
@@ -202,8 +202,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
||||
if (!current)
|
||||
break;
|
||||
|
||||
if (!_validate_no_foreign())
|
||||
break;
|
||||
//if (!_validate_no_foreign())
|
||||
// break;
|
||||
connect_dialog->popup_centered_ratio();
|
||||
connect_dialog->set_node(current);
|
||||
|
||||
@@ -213,8 +213,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
||||
Node *current = scene_tree->get_selected();
|
||||
if (!current)
|
||||
break;
|
||||
if (!_validate_no_foreign())
|
||||
break;
|
||||
//if (!_validate_no_foreign())
|
||||
// break;
|
||||
groups_editor->set_current(current);
|
||||
groups_editor->popup_centered_ratio();
|
||||
} break;
|
||||
@@ -224,8 +224,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
||||
if (!selected)
|
||||
break;
|
||||
|
||||
if (!_validate_no_foreign())
|
||||
break;
|
||||
//if (!_validate_no_foreign())
|
||||
// break;
|
||||
|
||||
Ref<Script> existing = selected->get_script();
|
||||
if (existing.is_valid())
|
||||
@@ -573,9 +573,9 @@ Node *SceneTreeDock::_duplicate(Node *p_node, Map<Node*,Node*> &duplimap) {
|
||||
|
||||
Ref<PackedScene> sd = ResourceLoader::load( p_node->get_filename() );
|
||||
ERR_FAIL_COND_V(!sd.is_valid(),NULL);
|
||||
node = sd->instance();
|
||||
node = sd->instance(true);
|
||||
ERR_FAIL_COND_V(!node,NULL);
|
||||
node->generate_instance_state();
|
||||
//node->generate_instance_state();
|
||||
} else {
|
||||
Object *obj = ObjectTypeDB::instance(p_node->get_type());
|
||||
ERR_FAIL_COND_V(!obj,NULL);
|
||||
@@ -874,6 +874,16 @@ bool SceneTreeDock::_validate_no_foreign() {
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (edited_scene->get_scene_instance_state().is_valid() && edited_scene->get_scene_instance_state()->find_node_by_path(edited_scene->get_path_to(E->get()))>=0) {
|
||||
|
||||
accept->get_ok()->set_text("Makes Sense!");
|
||||
accept->set_text("Can't operate on nodes the current scene inherits from!");
|
||||
accept->popup_centered_minsize();
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1078,14 +1088,15 @@ void SceneTreeDock::_delete_confirm() {
|
||||
void SceneTreeDock::_update_tool_buttons() {
|
||||
|
||||
Node *sel = scene_tree->get_selected();
|
||||
bool disable = !sel || (sel!=edited_scene && sel->get_owner()!=edited_scene);
|
||||
bool disable = !sel || (sel!=edited_scene && sel->get_owner()!=edited_scene) || (edited_scene->get_scene_instance_state().is_valid() && edited_scene->get_scene_instance_state()->find_node_by_path(edited_scene->get_path_to(sel))>=0);
|
||||
bool disable_root = disable || sel->get_parent()==scene_root;
|
||||
bool disable_edit = !sel;
|
||||
|
||||
tool_buttons[TOOL_INSTANCE]->set_disabled(disable);
|
||||
tool_buttons[TOOL_INSTANCE]->set_disabled(disable_edit);
|
||||
tool_buttons[TOOL_REPLACE]->set_disabled(disable);
|
||||
tool_buttons[TOOL_CONNECT]->set_disabled(disable);
|
||||
tool_buttons[TOOL_GROUP]->set_disabled(disable);
|
||||
tool_buttons[TOOL_SCRIPT]->set_disabled(disable);
|
||||
tool_buttons[TOOL_CONNECT]->set_disabled(disable_edit);
|
||||
tool_buttons[TOOL_GROUP]->set_disabled(disable_edit);
|
||||
tool_buttons[TOOL_SCRIPT]->set_disabled(disable_edit);
|
||||
tool_buttons[TOOL_MOVE_UP]->set_disabled(disable_root);
|
||||
tool_buttons[TOOL_MOVE_DOWN]->set_disabled(disable_root);
|
||||
tool_buttons[TOOL_DUPLICATE]->set_disabled(disable_root);
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#include "scene/main/viewport.h"
|
||||
#include "tools/editor/plugins/canvas_item_editor_plugin.h"
|
||||
|
||||
#include "scene/resources/packed_scene.h"
|
||||
|
||||
Node *SceneTreeEditor::get_scene_node() {
|
||||
|
||||
ERR_FAIL_COND_V(!is_inside_tree(),NULL);
|
||||
@@ -57,22 +59,58 @@ void SceneTreeEditor::_subscene_option(int p_idx) {
|
||||
|
||||
switch(p_idx) {
|
||||
|
||||
case SCENE_MENU_SHOW_CHILDREN: {
|
||||
case SCENE_MENU_EDITABLE_CHILDREN: {
|
||||
|
||||
if (node->has_meta("__editor_show_subtree")) {
|
||||
instance_menu->set_item_checked(0,true);
|
||||
node->set_meta("__editor_show_subtree",Variant());
|
||||
_update_tree();
|
||||
} else {
|
||||
node->set_meta("__editor_show_subtree",true);
|
||||
_update_tree();
|
||||
bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node);
|
||||
editable = !editable;
|
||||
|
||||
//node->set_instance_children_editable(editable);
|
||||
EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node,editable);
|
||||
instance_menu->set_item_checked(0,editable);
|
||||
if (editable) {
|
||||
node->set_scene_instance_load_placeholder(false);
|
||||
instance_menu->set_item_checked(1,false);
|
||||
}
|
||||
|
||||
_update_tree();
|
||||
|
||||
} break;
|
||||
case SCENE_MENU_USE_PLACEHOLDER: {
|
||||
|
||||
bool placeholder = node->get_scene_instance_load_placeholder();
|
||||
placeholder = !placeholder;
|
||||
|
||||
//node->set_instance_children_editable(editable);
|
||||
if (placeholder) {
|
||||
EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node,false);
|
||||
}
|
||||
node->set_scene_instance_load_placeholder(placeholder);
|
||||
instance_menu->set_item_checked(0,false);
|
||||
instance_menu->set_item_checked(1,placeholder);
|
||||
|
||||
_update_tree();
|
||||
|
||||
} break;
|
||||
case SCENE_MENU_OPEN: {
|
||||
|
||||
emit_signal("open",node->get_filename());
|
||||
} break;
|
||||
case SCENE_MENU_CLEAR_INHERITANCE: {
|
||||
clear_inherit_confirm->popup_centered_minsize();
|
||||
} break;
|
||||
case SCENE_MENU_OPEN_INHERITED: {
|
||||
if (node && node->get_scene_inherited_state().is_valid()) {
|
||||
emit_signal("open",node->get_scene_inherited_state()->get_path());
|
||||
}
|
||||
} break;
|
||||
case SCENE_MENU_CLEAR_INHERITANCE_CONFIRM: {
|
||||
if (node && node->get_scene_inherited_state().is_valid()) {
|
||||
node->set_scene_inherited_state(Ref<SceneState>());
|
||||
update_tree();
|
||||
EditorNode::get_singleton()->get_property_editor()->update_tree();
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
}
|
||||
|
||||
@@ -94,15 +132,33 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item,int p_column,int p_id)
|
||||
Rect2 item_rect = tree->get_item_rect(item,0);
|
||||
item_rect.pos.y-=tree->get_scroll().y;
|
||||
item_rect.pos+=tree->get_global_pos();
|
||||
instance_menu->set_pos(item_rect.pos+Vector2(0,item_rect.size.y));
|
||||
instance_menu->set_size(Vector2(item_rect.size.x,0));
|
||||
if (n->has_meta("__editor_show_subtree"))
|
||||
instance_menu->set_item_checked(0,true);
|
||||
else
|
||||
instance_menu->set_item_checked(0,false);
|
||||
|
||||
instance_menu->popup();
|
||||
instance_node=n->get_instance_ID();
|
||||
if (n==get_scene_node()) {
|
||||
inheritance_menu->set_pos(item_rect.pos+Vector2(0,item_rect.size.y));
|
||||
inheritance_menu->set_size(Vector2(item_rect.size.x,0));
|
||||
inheritance_menu->popup();
|
||||
instance_node=n->get_instance_ID();
|
||||
|
||||
} else {
|
||||
instance_menu->set_pos(item_rect.pos+Vector2(0,item_rect.size.y));
|
||||
instance_menu->set_size(Vector2(item_rect.size.x,0));
|
||||
if (EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(n))
|
||||
instance_menu->set_item_checked(0,true);
|
||||
else
|
||||
instance_menu->set_item_checked(0,false);
|
||||
|
||||
if (n->get_owner()==get_scene_node()) {
|
||||
instance_menu->set_item_checked(1,n->get_scene_instance_load_placeholder());
|
||||
instance_menu->set_item_disabled(1,false);
|
||||
} else {
|
||||
|
||||
instance_menu->set_item_checked(1,false);
|
||||
instance_menu->set_item_disabled(1,true);
|
||||
}
|
||||
|
||||
instance_menu->popup();
|
||||
instance_node=n->get_instance_ID();
|
||||
}
|
||||
//emit_signal("open",n->get_filename());
|
||||
} else if (p_id==BUTTON_SCRIPT) {
|
||||
RefPtr script=n->get_script();
|
||||
@@ -168,15 +224,17 @@ void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
|
||||
|
||||
bool part_of_subscene=false;
|
||||
|
||||
if (!display_foreign && p_node->get_owner()!=get_scene_node() && p_node!=get_scene_node()) {
|
||||
if (!display_foreign && p_node->get_owner()!=get_scene_node() && p_node!=get_scene_node()) {
|
||||
|
||||
if ((show_enabled_subscene || can_open_instance) && p_node->get_owner() && p_node->get_owner()->get_owner()==get_scene_node() && p_node->get_owner()->has_meta("__editor_show_subtree")) {
|
||||
if ((show_enabled_subscene || can_open_instance) && p_node->get_owner() && (get_scene_node()->is_editable_instance(p_node->get_owner()))) {
|
||||
|
||||
part_of_subscene=true;
|
||||
//allow
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
part_of_subscene = get_scene_node()->get_scene_inherited_state().is_valid() && get_scene_node()->get_scene_inherited_state()->find_node_by_path(get_scene_node()->get_path_to(p_node))>=0;
|
||||
}
|
||||
|
||||
TreeItem *item = tree->create_item(p_parent);
|
||||
@@ -199,6 +257,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
|
||||
icon=get_icon( (has_icon(p_node->get_type(),"EditorIcons")?p_node->get_type():String("Object")),"EditorIcons");
|
||||
item->set_icon(0, icon );
|
||||
item->set_metadata( 0,p_node->get_path() );
|
||||
|
||||
if (part_of_subscene) {
|
||||
|
||||
//item->set_selectable(0,marked_selectable);
|
||||
@@ -221,7 +280,10 @@ void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
|
||||
}
|
||||
}
|
||||
|
||||
if (p_node!=get_scene_node() && p_node->get_filename()!="" && can_open_instance) {
|
||||
if (p_node==get_scene_node() && p_node->get_scene_inherited_state().is_valid()) {
|
||||
item->add_button(0,get_icon("InstanceOptions","EditorIcons"),BUTTON_SUBSCENE);
|
||||
item->set_tooltip(0,"Inherits: "+p_node->get_scene_inherited_state()->get_path()+"\nType: "+p_node->get_type());
|
||||
} else if (p_node!=get_scene_node() && p_node->get_filename()!="" && can_open_instance) {
|
||||
|
||||
item->add_button(0,get_icon("InstanceOptions","EditorIcons"),BUTTON_SUBSCENE);
|
||||
item->set_tooltip(0,"Instance: "+p_node->get_filename()+"\nType: "+p_node->get_type());
|
||||
@@ -487,8 +549,11 @@ void SceneTreeEditor::_notification(int p_what) {
|
||||
|
||||
get_tree()->connect("tree_changed",this,"_tree_changed");
|
||||
get_tree()->connect("node_removed",this,"_node_removed");
|
||||
instance_menu->set_item_icon(2,get_icon("Load","EditorIcons"));
|
||||
instance_menu->set_item_icon(3,get_icon("Load","EditorIcons"));
|
||||
tree->connect("item_collapsed",this,"_cell_collapsed");
|
||||
inheritance_menu->set_item_icon(2,get_icon("Load","EditorIcons"));
|
||||
clear_inherit_confirm->connect("confirmed",this,"_subscene_option",varray(SCENE_MENU_CLEAR_INHERITANCE_CONFIRM));
|
||||
|
||||
|
||||
// get_scene()->connect("tree_changed",this,"_tree_changed",Vector<Variant>(),CONNECT_DEFERRED);
|
||||
// get_scene()->connect("node_removed",this,"_node_removed",Vector<Variant>(),CONNECT_DEFERRED);
|
||||
@@ -499,6 +564,7 @@ void SceneTreeEditor::_notification(int p_what) {
|
||||
get_tree()->disconnect("tree_changed",this,"_tree_changed");
|
||||
get_tree()->disconnect("node_removed",this,"_node_removed");
|
||||
tree->disconnect("item_collapsed",this,"_cell_collapsed");
|
||||
clear_inherit_confirm->disconnect("confirmed",this,"_subscene_option");
|
||||
_update_tree();
|
||||
}
|
||||
|
||||
@@ -788,12 +854,27 @@ SceneTreeEditor::SceneTreeEditor(bool p_label,bool p_can_rename, bool p_can_open
|
||||
blocked=0;
|
||||
|
||||
instance_menu = memnew( PopupMenu );
|
||||
instance_menu->add_check_item("Show Children",SCENE_MENU_SHOW_CHILDREN);
|
||||
instance_menu->add_check_item("Editable Children",SCENE_MENU_EDITABLE_CHILDREN);
|
||||
instance_menu->add_check_item("Load As Placeholder",SCENE_MENU_USE_PLACEHOLDER);
|
||||
instance_menu->add_separator();
|
||||
instance_menu->add_item("Open in Editor",SCENE_MENU_OPEN);
|
||||
instance_menu->connect("item_pressed",this,"_subscene_option");
|
||||
add_child(instance_menu);
|
||||
|
||||
inheritance_menu = memnew( PopupMenu );
|
||||
inheritance_menu->add_item("Clear Inheritance",SCENE_MENU_CLEAR_INHERITANCE);
|
||||
inheritance_menu->add_separator();
|
||||
inheritance_menu->add_item("Open in Editor",SCENE_MENU_OPEN_INHERITED);
|
||||
inheritance_menu->connect("item_pressed",this,"_subscene_option");
|
||||
|
||||
add_child(inheritance_menu);
|
||||
|
||||
clear_inherit_confirm = memnew( ConfirmationDialog );
|
||||
clear_inherit_confirm->set_text("Clear Inheritance? (No Undo!)");
|
||||
clear_inherit_confirm->get_ok()->set_text("Clear!");
|
||||
add_child(clear_inherit_confirm);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -52,16 +52,22 @@ class SceneTreeEditor : public Control {
|
||||
};
|
||||
|
||||
enum {
|
||||
SCENE_MENU_SHOW_CHILDREN,
|
||||
SCENE_MENU_EDITABLE_CHILDREN,
|
||||
SCENE_MENU_USE_PLACEHOLDER,
|
||||
SCENE_MENU_OPEN,
|
||||
SCENE_MENU_CLEAR_INHERITANCE,
|
||||
SCENE_MENU_OPEN_INHERITED,
|
||||
SCENE_MENU_CLEAR_INHERITANCE_CONFIRM,
|
||||
};
|
||||
|
||||
Tree *tree;
|
||||
Node *selected;
|
||||
PopupMenu *instance_menu;
|
||||
PopupMenu *inheritance_menu;
|
||||
ObjectID instance_node;
|
||||
|
||||
AcceptDialog *error;
|
||||
ConfirmationDialog *clear_inherit_confirm;
|
||||
|
||||
int blocked;
|
||||
|
||||
|
||||
@@ -104,11 +104,6 @@ class ExportDAE(bpy.types.Operator, ExportHelper):
|
||||
description="Export only objects on the active layers.",
|
||||
default=True,
|
||||
)
|
||||
use_exclude_ctrl_bones = BoolProperty(
|
||||
name="Exclude Control Bones",
|
||||
description="Exclude skeleton bones with names that begin with 'ctrl'.",
|
||||
default=True,
|
||||
)
|
||||
use_anim = BoolProperty(
|
||||
name="Export Animation",
|
||||
description="Export keyframe animation",
|
||||
|
||||
Reference in New Issue
Block a user